Edit on GitHub

Expressions

Every AST node in SQLGlot is represented by a subclass of Expression.

This module contains the implementation of all supported Expression types. Additionally, it exposes a number of helper functions, which are mainly used to programmatically build SQL expressions, such as sqlglot.expressions.select.


   1"""
   2## Expressions
   3
   4Every AST node in SQLGlot is represented by a subclass of `Expression`.
   5
   6This module contains the implementation of all supported `Expression` types. Additionally,
   7it exposes a number of helper functions, which are mainly used to programmatically build
   8SQL expressions, such as `sqlglot.expressions.select`.
   9
  10----
  11"""
  12
  13from __future__ import annotations
  14import datetime
  15import math
  16import numbers
  17import re
  18import textwrap
  19import typing as t
  20from collections import deque
  21from copy import deepcopy
  22from decimal import Decimal
  23from enum import auto
  24from functools import reduce
  25
  26from sqlglot.errors import ErrorLevel, ParseError
  27from sqlglot.helper import (
  28    AutoName,
  29    camel_to_snake_case,
  30    ensure_collection,
  31    ensure_list,
  32    seq_get,
  33    subclasses,
  34    to_bool,
  35)
  36from sqlglot.tokens import Token, TokenError
  37
  38if t.TYPE_CHECKING:
  39    from typing_extensions import Self
  40    from sqlglot._typing import E, Lit
  41    from sqlglot.dialects.dialect import DialectType
  42
  43    Q = t.TypeVar("Q", bound="Query")
  44    S = t.TypeVar("S", bound="SetOperation")
  45
  46
  47class _Expression(type):
  48    def __new__(cls, clsname, bases, attrs):
  49        klass = super().__new__(cls, clsname, bases, attrs)
  50
  51        # When an Expression class is created, its key is automatically set to be
  52        # the lowercase version of the class' name.
  53        klass.key = clsname.lower()
  54
  55        # This is so that docstrings are not inherited in pdoc
  56        klass.__doc__ = klass.__doc__ or ""
  57
  58        return klass
  59
  60
  61SQLGLOT_META = "sqlglot.meta"
  62SQLGLOT_ANONYMOUS = "sqlglot.anonymous"
  63TABLE_PARTS = ("this", "db", "catalog")
  64COLUMN_PARTS = ("this", "table", "db", "catalog")
  65
  66
  67class Expression(metaclass=_Expression):
  68    """
  69    The base class for all expressions in a syntax tree. Each Expression encapsulates any necessary
  70    context, such as its child expressions, their names (arg keys), and whether a given child expression
  71    is optional or not.
  72
  73    Attributes:
  74        key: a unique key for each class in the Expression hierarchy. This is useful for hashing
  75            and representing expressions as strings.
  76        arg_types: determines the arguments (child nodes) supported by an expression. It maps
  77            arg keys to booleans that indicate whether the corresponding args are optional.
  78        parent: a reference to the parent expression (or None, in case of root expressions).
  79        arg_key: the arg key an expression is associated with, i.e. the name its parent expression
  80            uses to refer to it.
  81        index: the index of an expression if it is inside of a list argument in its parent.
  82        comments: a list of comments that are associated with a given expression. This is used in
  83            order to preserve comments when transpiling SQL code.
  84        type: the `sqlglot.expressions.DataType` type of an expression. This is inferred by the
  85            optimizer, in order to enable some transformations that require type information.
  86        meta: a dictionary that can be used to store useful metadata for a given expression.
  87
  88    Example:
  89        >>> class Foo(Expression):
  90        ...     arg_types = {"this": True, "expression": False}
  91
  92        The above definition informs us that Foo is an Expression that requires an argument called
  93        "this" and may also optionally receive an argument called "expression".
  94
  95    Args:
  96        args: a mapping used for retrieving the arguments of an expression, given their arg keys.
  97    """
  98
  99    key = "expression"
 100    arg_types = {"this": True}
 101    __slots__ = ("args", "parent", "arg_key", "index", "comments", "_type", "_meta", "_hash")
 102
 103    def __init__(self, **args: t.Any):
 104        self.args: t.Dict[str, t.Any] = args
 105        self.parent: t.Optional[Expression] = None
 106        self.arg_key: t.Optional[str] = None
 107        self.index: t.Optional[int] = None
 108        self.comments: t.Optional[t.List[str]] = None
 109        self._type: t.Optional[DataType] = None
 110        self._meta: t.Optional[t.Dict[str, t.Any]] = None
 111        self._hash: t.Optional[int] = None
 112
 113        for arg_key, value in self.args.items():
 114            self._set_parent(arg_key, value)
 115
 116    def __eq__(self, other) -> bool:
 117        return type(self) is type(other) and hash(self) == hash(other)
 118
 119    @property
 120    def hashable_args(self) -> t.Any:
 121        return frozenset(
 122            (k, tuple(_norm_arg(a) for a in v) if type(v) is list else _norm_arg(v))
 123            for k, v in self.args.items()
 124            if not (v is None or v is False or (type(v) is list and not v))
 125        )
 126
 127    def __hash__(self) -> int:
 128        if self._hash is not None:
 129            return self._hash
 130
 131        return hash((self.__class__, self.hashable_args))
 132
 133    @property
 134    def this(self) -> t.Any:
 135        """
 136        Retrieves the argument with key "this".
 137        """
 138        return self.args.get("this")
 139
 140    @property
 141    def expression(self) -> t.Any:
 142        """
 143        Retrieves the argument with key "expression".
 144        """
 145        return self.args.get("expression")
 146
 147    @property
 148    def expressions(self) -> t.List[t.Any]:
 149        """
 150        Retrieves the argument with key "expressions".
 151        """
 152        return self.args.get("expressions") or []
 153
 154    def text(self, key) -> str:
 155        """
 156        Returns a textual representation of the argument corresponding to "key". This can only be used
 157        for args that are strings or leaf Expression instances, such as identifiers and literals.
 158        """
 159        field = self.args.get(key)
 160        if isinstance(field, str):
 161            return field
 162        if isinstance(field, (Identifier, Literal, Var)):
 163            return field.this
 164        if isinstance(field, (Star, Null)):
 165            return field.name
 166        return ""
 167
 168    @property
 169    def is_string(self) -> bool:
 170        """
 171        Checks whether a Literal expression is a string.
 172        """
 173        return isinstance(self, Literal) and self.args["is_string"]
 174
 175    @property
 176    def is_number(self) -> bool:
 177        """
 178        Checks whether a Literal expression is a number.
 179        """
 180        return (isinstance(self, Literal) and not self.args["is_string"]) or (
 181            isinstance(self, Neg) and self.this.is_number
 182        )
 183
 184    def to_py(self) -> t.Any:
 185        """
 186        Returns a Python object equivalent of the SQL node.
 187        """
 188        raise ValueError(f"{self} cannot be converted to a Python object.")
 189
 190    @property
 191    def is_int(self) -> bool:
 192        """
 193        Checks whether an expression is an integer.
 194        """
 195        return self.is_number and isinstance(self.to_py(), int)
 196
 197    @property
 198    def is_star(self) -> bool:
 199        """Checks whether an expression is a star."""
 200        return isinstance(self, Star) or (isinstance(self, Column) and isinstance(self.this, Star))
 201
 202    @property
 203    def alias(self) -> str:
 204        """
 205        Returns the alias of the expression, or an empty string if it's not aliased.
 206        """
 207        if isinstance(self.args.get("alias"), TableAlias):
 208            return self.args["alias"].name
 209        return self.text("alias")
 210
 211    @property
 212    def alias_column_names(self) -> t.List[str]:
 213        table_alias = self.args.get("alias")
 214        if not table_alias:
 215            return []
 216        return [c.name for c in table_alias.args.get("columns") or []]
 217
 218    @property
 219    def name(self) -> str:
 220        return self.text("this")
 221
 222    @property
 223    def alias_or_name(self) -> str:
 224        return self.alias or self.name
 225
 226    @property
 227    def output_name(self) -> str:
 228        """
 229        Name of the output column if this expression is a selection.
 230
 231        If the Expression has no output name, an empty string is returned.
 232
 233        Example:
 234            >>> from sqlglot import parse_one
 235            >>> parse_one("SELECT a").expressions[0].output_name
 236            'a'
 237            >>> parse_one("SELECT b AS c").expressions[0].output_name
 238            'c'
 239            >>> parse_one("SELECT 1 + 2").expressions[0].output_name
 240            ''
 241        """
 242        return ""
 243
 244    @property
 245    def type(self) -> t.Optional[DataType]:
 246        return self._type
 247
 248    @type.setter
 249    def type(self, dtype: t.Optional[DataType | DataType.Type | str]) -> None:
 250        if dtype and not isinstance(dtype, DataType):
 251            dtype = DataType.build(dtype)
 252        self._type = dtype  # type: ignore
 253
 254    def is_type(self, *dtypes) -> bool:
 255        return self.type is not None and self.type.is_type(*dtypes)
 256
 257    def is_leaf(self) -> bool:
 258        return not any(isinstance(v, (Expression, list)) for v in self.args.values())
 259
 260    @property
 261    def meta(self) -> t.Dict[str, t.Any]:
 262        if self._meta is None:
 263            self._meta = {}
 264        return self._meta
 265
 266    def __deepcopy__(self, memo):
 267        root = self.__class__()
 268        stack = [(self, root)]
 269
 270        while stack:
 271            node, copy = stack.pop()
 272
 273            if node.comments is not None:
 274                copy.comments = deepcopy(node.comments)
 275            if node._type is not None:
 276                copy._type = deepcopy(node._type)
 277            if node._meta is not None:
 278                copy._meta = deepcopy(node._meta)
 279            if node._hash is not None:
 280                copy._hash = node._hash
 281
 282            for k, vs in node.args.items():
 283                if hasattr(vs, "parent"):
 284                    stack.append((vs, vs.__class__()))
 285                    copy.set(k, stack[-1][-1])
 286                elif type(vs) is list:
 287                    copy.args[k] = []
 288
 289                    for v in vs:
 290                        if hasattr(v, "parent"):
 291                            stack.append((v, v.__class__()))
 292                            copy.append(k, stack[-1][-1])
 293                        else:
 294                            copy.append(k, v)
 295                else:
 296                    copy.args[k] = vs
 297
 298        return root
 299
 300    def copy(self) -> Self:
 301        """
 302        Returns a deep copy of the expression.
 303        """
 304        return deepcopy(self)
 305
 306    def add_comments(self, comments: t.Optional[t.List[str]] = None, prepend: bool = False) -> None:
 307        if self.comments is None:
 308            self.comments = []
 309
 310        if comments:
 311            for comment in comments:
 312                _, *meta = comment.split(SQLGLOT_META)
 313                if meta:
 314                    for kv in "".join(meta).split(","):
 315                        k, *v = kv.split("=")
 316                        value = v[0].strip() if v else True
 317                        self.meta[k.strip()] = to_bool(value)
 318
 319                if not prepend:
 320                    self.comments.append(comment)
 321
 322            if prepend:
 323                self.comments = comments + self.comments
 324
 325    def pop_comments(self) -> t.List[str]:
 326        comments = self.comments or []
 327        self.comments = None
 328        return comments
 329
 330    def append(self, arg_key: str, value: t.Any) -> None:
 331        """
 332        Appends value to arg_key if it's a list or sets it as a new list.
 333
 334        Args:
 335            arg_key (str): name of the list expression arg
 336            value (Any): value to append to the list
 337        """
 338        if type(self.args.get(arg_key)) is not list:
 339            self.args[arg_key] = []
 340        self._set_parent(arg_key, value)
 341        values = self.args[arg_key]
 342        if hasattr(value, "parent"):
 343            value.index = len(values)
 344        values.append(value)
 345
 346    def set(
 347        self,
 348        arg_key: str,
 349        value: t.Any,
 350        index: t.Optional[int] = None,
 351        overwrite: bool = True,
 352    ) -> None:
 353        """
 354        Sets arg_key to value.
 355
 356        Args:
 357            arg_key: name of the expression arg.
 358            value: value to set the arg to.
 359            index: if the arg is a list, this specifies what position to add the value in it.
 360            overwrite: assuming an index is given, this determines whether to overwrite the
 361                list entry instead of only inserting a new value (i.e., like list.insert).
 362        """
 363        if index is not None:
 364            expressions = self.args.get(arg_key) or []
 365
 366            if seq_get(expressions, index) is None:
 367                return
 368            if value is None:
 369                expressions.pop(index)
 370                for v in expressions[index:]:
 371                    v.index = v.index - 1
 372                return
 373
 374            if isinstance(value, list):
 375                expressions.pop(index)
 376                expressions[index:index] = value
 377            elif overwrite:
 378                expressions[index] = value
 379            else:
 380                expressions.insert(index, value)
 381
 382            value = expressions
 383        elif value is None:
 384            self.args.pop(arg_key, None)
 385            return
 386
 387        self.args[arg_key] = value
 388        self._set_parent(arg_key, value, index)
 389
 390    def _set_parent(self, arg_key: str, value: t.Any, index: t.Optional[int] = None) -> None:
 391        if hasattr(value, "parent"):
 392            value.parent = self
 393            value.arg_key = arg_key
 394            value.index = index
 395        elif type(value) is list:
 396            for index, v in enumerate(value):
 397                if hasattr(v, "parent"):
 398                    v.parent = self
 399                    v.arg_key = arg_key
 400                    v.index = index
 401
 402    @property
 403    def depth(self) -> int:
 404        """
 405        Returns the depth of this tree.
 406        """
 407        if self.parent:
 408            return self.parent.depth + 1
 409        return 0
 410
 411    def iter_expressions(self, reverse: bool = False) -> t.Iterator[Expression]:
 412        """Yields the key and expression for all arguments, exploding list args."""
 413        # remove tuple when python 3.7 is deprecated
 414        for vs in reversed(tuple(self.args.values())) if reverse else self.args.values():  # type: ignore
 415            if type(vs) is list:
 416                for v in reversed(vs) if reverse else vs:  # type: ignore
 417                    if hasattr(v, "parent"):
 418                        yield v
 419            else:
 420                if hasattr(vs, "parent"):
 421                    yield vs
 422
 423    def find(self, *expression_types: t.Type[E], bfs: bool = True) -> t.Optional[E]:
 424        """
 425        Returns the first node in this tree which matches at least one of
 426        the specified types.
 427
 428        Args:
 429            expression_types: the expression type(s) to match.
 430            bfs: whether to search the AST using the BFS algorithm (DFS is used if false).
 431
 432        Returns:
 433            The node which matches the criteria or None if no such node was found.
 434        """
 435        return next(self.find_all(*expression_types, bfs=bfs), None)
 436
 437    def find_all(self, *expression_types: t.Type[E], bfs: bool = True) -> t.Iterator[E]:
 438        """
 439        Returns a generator object which visits all nodes in this tree and only
 440        yields those that match at least one of the specified expression types.
 441
 442        Args:
 443            expression_types: the expression type(s) to match.
 444            bfs: whether to search the AST using the BFS algorithm (DFS is used if false).
 445
 446        Returns:
 447            The generator object.
 448        """
 449        for expression in self.walk(bfs=bfs):
 450            if isinstance(expression, expression_types):
 451                yield expression
 452
 453    def find_ancestor(self, *expression_types: t.Type[E]) -> t.Optional[E]:
 454        """
 455        Returns a nearest parent matching expression_types.
 456
 457        Args:
 458            expression_types: the expression type(s) to match.
 459
 460        Returns:
 461            The parent node.
 462        """
 463        ancestor = self.parent
 464        while ancestor and not isinstance(ancestor, expression_types):
 465            ancestor = ancestor.parent
 466        return ancestor  # type: ignore
 467
 468    @property
 469    def parent_select(self) -> t.Optional[Select]:
 470        """
 471        Returns the parent select statement.
 472        """
 473        return self.find_ancestor(Select)
 474
 475    @property
 476    def same_parent(self) -> bool:
 477        """Returns if the parent is the same class as itself."""
 478        return type(self.parent) is self.__class__
 479
 480    def root(self) -> Expression:
 481        """
 482        Returns the root expression of this tree.
 483        """
 484        expression = self
 485        while expression.parent:
 486            expression = expression.parent
 487        return expression
 488
 489    def walk(
 490        self, bfs: bool = True, prune: t.Optional[t.Callable[[Expression], bool]] = None
 491    ) -> t.Iterator[Expression]:
 492        """
 493        Returns a generator object which visits all nodes in this tree.
 494
 495        Args:
 496            bfs: if set to True the BFS traversal order will be applied,
 497                otherwise the DFS traversal will be used instead.
 498            prune: callable that returns True if the generator should stop traversing
 499                this branch of the tree.
 500
 501        Returns:
 502            the generator object.
 503        """
 504        if bfs:
 505            yield from self.bfs(prune=prune)
 506        else:
 507            yield from self.dfs(prune=prune)
 508
 509    def dfs(
 510        self, prune: t.Optional[t.Callable[[Expression], bool]] = None
 511    ) -> t.Iterator[Expression]:
 512        """
 513        Returns a generator object which visits all nodes in this tree in
 514        the DFS (Depth-first) order.
 515
 516        Returns:
 517            The generator object.
 518        """
 519        stack = [self]
 520
 521        while stack:
 522            node = stack.pop()
 523
 524            yield node
 525
 526            if prune and prune(node):
 527                continue
 528
 529            for v in node.iter_expressions(reverse=True):
 530                stack.append(v)
 531
 532    def bfs(
 533        self, prune: t.Optional[t.Callable[[Expression], bool]] = None
 534    ) -> t.Iterator[Expression]:
 535        """
 536        Returns a generator object which visits all nodes in this tree in
 537        the BFS (Breadth-first) order.
 538
 539        Returns:
 540            The generator object.
 541        """
 542        queue = deque([self])
 543
 544        while queue:
 545            node = queue.popleft()
 546
 547            yield node
 548
 549            if prune and prune(node):
 550                continue
 551
 552            for v in node.iter_expressions():
 553                queue.append(v)
 554
 555    def unnest(self):
 556        """
 557        Returns the first non parenthesis child or self.
 558        """
 559        expression = self
 560        while type(expression) is Paren:
 561            expression = expression.this
 562        return expression
 563
 564    def unalias(self):
 565        """
 566        Returns the inner expression if this is an Alias.
 567        """
 568        if isinstance(self, Alias):
 569            return self.this
 570        return self
 571
 572    def unnest_operands(self):
 573        """
 574        Returns unnested operands as a tuple.
 575        """
 576        return tuple(arg.unnest() for arg in self.iter_expressions())
 577
 578    def flatten(self, unnest=True):
 579        """
 580        Returns a generator which yields child nodes whose parents are the same class.
 581
 582        A AND B AND C -> [A, B, C]
 583        """
 584        for node in self.dfs(prune=lambda n: n.parent and type(n) is not self.__class__):
 585            if type(node) is not self.__class__:
 586                yield node.unnest() if unnest and not isinstance(node, Subquery) else node
 587
 588    def __str__(self) -> str:
 589        return self.sql()
 590
 591    def __repr__(self) -> str:
 592        return _to_s(self)
 593
 594    def to_s(self) -> str:
 595        """
 596        Same as __repr__, but includes additional information which can be useful
 597        for debugging, like empty or missing args and the AST nodes' object IDs.
 598        """
 599        return _to_s(self, verbose=True)
 600
 601    def sql(self, dialect: DialectType = None, **opts) -> str:
 602        """
 603        Returns SQL string representation of this tree.
 604
 605        Args:
 606            dialect: the dialect of the output SQL string (eg. "spark", "hive", "presto", "mysql").
 607            opts: other `sqlglot.generator.Generator` options.
 608
 609        Returns:
 610            The SQL string.
 611        """
 612        from sqlglot.dialects import Dialect
 613
 614        return Dialect.get_or_raise(dialect).generate(self, **opts)
 615
 616    def transform(self, fun: t.Callable, *args: t.Any, copy: bool = True, **kwargs) -> Expression:
 617        """
 618        Visits all tree nodes (excluding already transformed ones)
 619        and applies the given transformation function to each node.
 620
 621        Args:
 622            fun: a function which takes a node as an argument and returns a
 623                new transformed node or the same node without modifications. If the function
 624                returns None, then the corresponding node will be removed from the syntax tree.
 625            copy: if set to True a new tree instance is constructed, otherwise the tree is
 626                modified in place.
 627
 628        Returns:
 629            The transformed tree.
 630        """
 631        root = None
 632        new_node = None
 633
 634        for node in (self.copy() if copy else self).dfs(prune=lambda n: n is not new_node):
 635            parent, arg_key, index = node.parent, node.arg_key, node.index
 636            new_node = fun(node, *args, **kwargs)
 637
 638            if not root:
 639                root = new_node
 640            elif parent and arg_key and new_node is not node:
 641                parent.set(arg_key, new_node, index)
 642
 643        assert root
 644        return root.assert_is(Expression)
 645
 646    @t.overload
 647    def replace(self, expression: E) -> E: ...
 648
 649    @t.overload
 650    def replace(self, expression: None) -> None: ...
 651
 652    def replace(self, expression):
 653        """
 654        Swap out this expression with a new expression.
 655
 656        For example::
 657
 658            >>> tree = Select().select("x").from_("tbl")
 659            >>> tree.find(Column).replace(column("y"))
 660            Column(
 661              this=Identifier(this=y, quoted=False))
 662            >>> tree.sql()
 663            'SELECT y FROM tbl'
 664
 665        Args:
 666            expression: new node
 667
 668        Returns:
 669            The new expression or expressions.
 670        """
 671        parent = self.parent
 672
 673        if not parent or parent is expression:
 674            return expression
 675
 676        key = self.arg_key
 677        value = parent.args.get(key)
 678
 679        if type(expression) is list and isinstance(value, Expression):
 680            # We are trying to replace an Expression with a list, so it's assumed that
 681            # the intention was to really replace the parent of this expression.
 682            value.parent.replace(expression)
 683        else:
 684            parent.set(key, expression, self.index)
 685
 686        if expression is not self:
 687            self.parent = None
 688            self.arg_key = None
 689            self.index = None
 690
 691        return expression
 692
 693    def pop(self: E) -> E:
 694        """
 695        Remove this expression from its AST.
 696
 697        Returns:
 698            The popped expression.
 699        """
 700        self.replace(None)
 701        return self
 702
 703    def assert_is(self, type_: t.Type[E]) -> E:
 704        """
 705        Assert that this `Expression` is an instance of `type_`.
 706
 707        If it is NOT an instance of `type_`, this raises an assertion error.
 708        Otherwise, this returns this expression.
 709
 710        Examples:
 711            This is useful for type security in chained expressions:
 712
 713            >>> import sqlglot
 714            >>> sqlglot.parse_one("SELECT x from y").assert_is(Select).select("z").sql()
 715            'SELECT x, z FROM y'
 716        """
 717        if not isinstance(self, type_):
 718            raise AssertionError(f"{self} is not {type_}.")
 719        return self
 720
 721    def error_messages(self, args: t.Optional[t.Sequence] = None) -> t.List[str]:
 722        """
 723        Checks if this expression is valid (e.g. all mandatory args are set).
 724
 725        Args:
 726            args: a sequence of values that were used to instantiate a Func expression. This is used
 727                to check that the provided arguments don't exceed the function argument limit.
 728
 729        Returns:
 730            A list of error messages for all possible errors that were found.
 731        """
 732        errors: t.List[str] = []
 733
 734        for k in self.args:
 735            if k not in self.arg_types:
 736                errors.append(f"Unexpected keyword: '{k}' for {self.__class__}")
 737        for k, mandatory in self.arg_types.items():
 738            v = self.args.get(k)
 739            if mandatory and (v is None or (isinstance(v, list) and not v)):
 740                errors.append(f"Required keyword: '{k}' missing for {self.__class__}")
 741
 742        if (
 743            args
 744            and isinstance(self, Func)
 745            and len(args) > len(self.arg_types)
 746            and not self.is_var_len_args
 747        ):
 748            errors.append(
 749                f"The number of provided arguments ({len(args)}) is greater than "
 750                f"the maximum number of supported arguments ({len(self.arg_types)})"
 751            )
 752
 753        return errors
 754
 755    def dump(self):
 756        """
 757        Dump this Expression to a JSON-serializable dict.
 758        """
 759        from sqlglot.serde import dump
 760
 761        return dump(self)
 762
 763    @classmethod
 764    def load(cls, obj):
 765        """
 766        Load a dict (as returned by `Expression.dump`) into an Expression instance.
 767        """
 768        from sqlglot.serde import load
 769
 770        return load(obj)
 771
 772    def and_(
 773        self,
 774        *expressions: t.Optional[ExpOrStr],
 775        dialect: DialectType = None,
 776        copy: bool = True,
 777        wrap: bool = True,
 778        **opts,
 779    ) -> Condition:
 780        """
 781        AND this condition with one or multiple expressions.
 782
 783        Example:
 784            >>> condition("x=1").and_("y=1").sql()
 785            'x = 1 AND y = 1'
 786
 787        Args:
 788            *expressions: the SQL code strings to parse.
 789                If an `Expression` instance is passed, it will be used as-is.
 790            dialect: the dialect used to parse the input expression.
 791            copy: whether to copy the involved expressions (only applies to Expressions).
 792            wrap: whether to wrap the operands in `Paren`s. This is true by default to avoid
 793                precedence issues, but can be turned off when the produced AST is too deep and
 794                causes recursion-related issues.
 795            opts: other options to use to parse the input expressions.
 796
 797        Returns:
 798            The new And condition.
 799        """
 800        return and_(self, *expressions, dialect=dialect, copy=copy, wrap=wrap, **opts)
 801
 802    def or_(
 803        self,
 804        *expressions: t.Optional[ExpOrStr],
 805        dialect: DialectType = None,
 806        copy: bool = True,
 807        wrap: bool = True,
 808        **opts,
 809    ) -> Condition:
 810        """
 811        OR this condition with one or multiple expressions.
 812
 813        Example:
 814            >>> condition("x=1").or_("y=1").sql()
 815            'x = 1 OR y = 1'
 816
 817        Args:
 818            *expressions: the SQL code strings to parse.
 819                If an `Expression` instance is passed, it will be used as-is.
 820            dialect: the dialect used to parse the input expression.
 821            copy: whether to copy the involved expressions (only applies to Expressions).
 822            wrap: whether to wrap the operands in `Paren`s. This is true by default to avoid
 823                precedence issues, but can be turned off when the produced AST is too deep and
 824                causes recursion-related issues.
 825            opts: other options to use to parse the input expressions.
 826
 827        Returns:
 828            The new Or condition.
 829        """
 830        return or_(self, *expressions, dialect=dialect, copy=copy, wrap=wrap, **opts)
 831
 832    def not_(self, copy: bool = True):
 833        """
 834        Wrap this condition with NOT.
 835
 836        Example:
 837            >>> condition("x=1").not_().sql()
 838            'NOT x = 1'
 839
 840        Args:
 841            copy: whether to copy this object.
 842
 843        Returns:
 844            The new Not instance.
 845        """
 846        return not_(self, copy=copy)
 847
 848    def as_(
 849        self,
 850        alias: str | Identifier,
 851        quoted: t.Optional[bool] = None,
 852        dialect: DialectType = None,
 853        copy: bool = True,
 854        **opts,
 855    ) -> Alias:
 856        return alias_(self, alias, quoted=quoted, dialect=dialect, copy=copy, **opts)
 857
 858    def _binop(self, klass: t.Type[E], other: t.Any, reverse: bool = False) -> E:
 859        this = self.copy()
 860        other = convert(other, copy=True)
 861        if not isinstance(this, klass) and not isinstance(other, klass):
 862            this = _wrap(this, Binary)
 863            other = _wrap(other, Binary)
 864        if reverse:
 865            return klass(this=other, expression=this)
 866        return klass(this=this, expression=other)
 867
 868    def __getitem__(self, other: ExpOrStr | t.Tuple[ExpOrStr]) -> Bracket:
 869        return Bracket(
 870            this=self.copy(), expressions=[convert(e, copy=True) for e in ensure_list(other)]
 871        )
 872
 873    def __iter__(self) -> t.Iterator:
 874        if "expressions" in self.arg_types:
 875            return iter(self.args.get("expressions") or [])
 876        # We define this because __getitem__ converts Expression into an iterable, which is
 877        # problematic because one can hit infinite loops if they do "for x in some_expr: ..."
 878        # See: https://peps.python.org/pep-0234/
 879        raise TypeError(f"'{self.__class__.__name__}' object is not iterable")
 880
 881    def isin(
 882        self,
 883        *expressions: t.Any,
 884        query: t.Optional[ExpOrStr] = None,
 885        unnest: t.Optional[ExpOrStr] | t.Collection[ExpOrStr] = None,
 886        copy: bool = True,
 887        **opts,
 888    ) -> In:
 889        subquery = maybe_parse(query, copy=copy, **opts) if query else None
 890        if subquery and not isinstance(subquery, Subquery):
 891            subquery = subquery.subquery(copy=False)
 892
 893        return In(
 894            this=maybe_copy(self, copy),
 895            expressions=[convert(e, copy=copy) for e in expressions],
 896            query=subquery,
 897            unnest=(
 898                Unnest(
 899                    expressions=[
 900                        maybe_parse(t.cast(ExpOrStr, e), copy=copy, **opts)
 901                        for e in ensure_list(unnest)
 902                    ]
 903                )
 904                if unnest
 905                else None
 906            ),
 907        )
 908
 909    def between(self, low: t.Any, high: t.Any, copy: bool = True, **opts) -> Between:
 910        return Between(
 911            this=maybe_copy(self, copy),
 912            low=convert(low, copy=copy, **opts),
 913            high=convert(high, copy=copy, **opts),
 914        )
 915
 916    def is_(self, other: ExpOrStr) -> Is:
 917        return self._binop(Is, other)
 918
 919    def like(self, other: ExpOrStr) -> Like:
 920        return self._binop(Like, other)
 921
 922    def ilike(self, other: ExpOrStr) -> ILike:
 923        return self._binop(ILike, other)
 924
 925    def eq(self, other: t.Any) -> EQ:
 926        return self._binop(EQ, other)
 927
 928    def neq(self, other: t.Any) -> NEQ:
 929        return self._binop(NEQ, other)
 930
 931    def rlike(self, other: ExpOrStr) -> RegexpLike:
 932        return self._binop(RegexpLike, other)
 933
 934    def div(self, other: ExpOrStr, typed: bool = False, safe: bool = False) -> Div:
 935        div = self._binop(Div, other)
 936        div.args["typed"] = typed
 937        div.args["safe"] = safe
 938        return div
 939
 940    def asc(self, nulls_first: bool = True) -> Ordered:
 941        return Ordered(this=self.copy(), nulls_first=nulls_first)
 942
 943    def desc(self, nulls_first: bool = False) -> Ordered:
 944        return Ordered(this=self.copy(), desc=True, nulls_first=nulls_first)
 945
 946    def __lt__(self, other: t.Any) -> LT:
 947        return self._binop(LT, other)
 948
 949    def __le__(self, other: t.Any) -> LTE:
 950        return self._binop(LTE, other)
 951
 952    def __gt__(self, other: t.Any) -> GT:
 953        return self._binop(GT, other)
 954
 955    def __ge__(self, other: t.Any) -> GTE:
 956        return self._binop(GTE, other)
 957
 958    def __add__(self, other: t.Any) -> Add:
 959        return self._binop(Add, other)
 960
 961    def __radd__(self, other: t.Any) -> Add:
 962        return self._binop(Add, other, reverse=True)
 963
 964    def __sub__(self, other: t.Any) -> Sub:
 965        return self._binop(Sub, other)
 966
 967    def __rsub__(self, other: t.Any) -> Sub:
 968        return self._binop(Sub, other, reverse=True)
 969
 970    def __mul__(self, other: t.Any) -> Mul:
 971        return self._binop(Mul, other)
 972
 973    def __rmul__(self, other: t.Any) -> Mul:
 974        return self._binop(Mul, other, reverse=True)
 975
 976    def __truediv__(self, other: t.Any) -> Div:
 977        return self._binop(Div, other)
 978
 979    def __rtruediv__(self, other: t.Any) -> Div:
 980        return self._binop(Div, other, reverse=True)
 981
 982    def __floordiv__(self, other: t.Any) -> IntDiv:
 983        return self._binop(IntDiv, other)
 984
 985    def __rfloordiv__(self, other: t.Any) -> IntDiv:
 986        return self._binop(IntDiv, other, reverse=True)
 987
 988    def __mod__(self, other: t.Any) -> Mod:
 989        return self._binop(Mod, other)
 990
 991    def __rmod__(self, other: t.Any) -> Mod:
 992        return self._binop(Mod, other, reverse=True)
 993
 994    def __pow__(self, other: t.Any) -> Pow:
 995        return self._binop(Pow, other)
 996
 997    def __rpow__(self, other: t.Any) -> Pow:
 998        return self._binop(Pow, other, reverse=True)
 999
1000    def __and__(self, other: t.Any) -> And:
1001        return self._binop(And, other)
1002
1003    def __rand__(self, other: t.Any) -> And:
1004        return self._binop(And, other, reverse=True)
1005
1006    def __or__(self, other: t.Any) -> Or:
1007        return self._binop(Or, other)
1008
1009    def __ror__(self, other: t.Any) -> Or:
1010        return self._binop(Or, other, reverse=True)
1011
1012    def __neg__(self) -> Neg:
1013        return Neg(this=_wrap(self.copy(), Binary))
1014
1015    def __invert__(self) -> Not:
1016        return not_(self.copy())
1017
1018
1019IntoType = t.Union[
1020    str,
1021    t.Type[Expression],
1022    t.Collection[t.Union[str, t.Type[Expression]]],
1023]
1024ExpOrStr = t.Union[str, Expression]
1025
1026
1027class Condition(Expression):
1028    """Logical conditions like x AND y, or simply x"""
1029
1030
1031class Predicate(Condition):
1032    """Relationships like x = y, x > 1, x >= y."""
1033
1034
1035class DerivedTable(Expression):
1036    @property
1037    def selects(self) -> t.List[Expression]:
1038        return self.this.selects if isinstance(self.this, Query) else []
1039
1040    @property
1041    def named_selects(self) -> t.List[str]:
1042        return [select.output_name for select in self.selects]
1043
1044
1045class Query(Expression):
1046    def subquery(self, alias: t.Optional[ExpOrStr] = None, copy: bool = True) -> Subquery:
1047        """
1048        Returns a `Subquery` that wraps around this query.
1049
1050        Example:
1051            >>> subquery = Select().select("x").from_("tbl").subquery()
1052            >>> Select().select("x").from_(subquery).sql()
1053            'SELECT x FROM (SELECT x FROM tbl)'
1054
1055        Args:
1056            alias: an optional alias for the subquery.
1057            copy: if `False`, modify this expression instance in-place.
1058        """
1059        instance = maybe_copy(self, copy)
1060        if not isinstance(alias, Expression):
1061            alias = TableAlias(this=to_identifier(alias)) if alias else None
1062
1063        return Subquery(this=instance, alias=alias)
1064
1065    def limit(
1066        self: Q, expression: ExpOrStr | int, dialect: DialectType = None, copy: bool = True, **opts
1067    ) -> Q:
1068        """
1069        Adds a LIMIT clause to this query.
1070
1071        Example:
1072            >>> select("1").union(select("1")).limit(1).sql()
1073            'SELECT 1 UNION SELECT 1 LIMIT 1'
1074
1075        Args:
1076            expression: the SQL code string to parse.
1077                This can also be an integer.
1078                If a `Limit` instance is passed, it will be used as-is.
1079                If another `Expression` instance is passed, it will be wrapped in a `Limit`.
1080            dialect: the dialect used to parse the input expression.
1081            copy: if `False`, modify this expression instance in-place.
1082            opts: other options to use to parse the input expressions.
1083
1084        Returns:
1085            A limited Select expression.
1086        """
1087        return _apply_builder(
1088            expression=expression,
1089            instance=self,
1090            arg="limit",
1091            into=Limit,
1092            prefix="LIMIT",
1093            dialect=dialect,
1094            copy=copy,
1095            into_arg="expression",
1096            **opts,
1097        )
1098
1099    def offset(
1100        self: Q, expression: ExpOrStr | int, dialect: DialectType = None, copy: bool = True, **opts
1101    ) -> Q:
1102        """
1103        Set the OFFSET expression.
1104
1105        Example:
1106            >>> Select().from_("tbl").select("x").offset(10).sql()
1107            'SELECT x FROM tbl OFFSET 10'
1108
1109        Args:
1110            expression: the SQL code string to parse.
1111                This can also be an integer.
1112                If a `Offset` instance is passed, this is used as-is.
1113                If another `Expression` instance is passed, it will be wrapped in a `Offset`.
1114            dialect: the dialect used to parse the input expression.
1115            copy: if `False`, modify this expression instance in-place.
1116            opts: other options to use to parse the input expressions.
1117
1118        Returns:
1119            The modified Select expression.
1120        """
1121        return _apply_builder(
1122            expression=expression,
1123            instance=self,
1124            arg="offset",
1125            into=Offset,
1126            prefix="OFFSET",
1127            dialect=dialect,
1128            copy=copy,
1129            into_arg="expression",
1130            **opts,
1131        )
1132
1133    def order_by(
1134        self: Q,
1135        *expressions: t.Optional[ExpOrStr],
1136        append: bool = True,
1137        dialect: DialectType = None,
1138        copy: bool = True,
1139        **opts,
1140    ) -> Q:
1141        """
1142        Set the ORDER BY expression.
1143
1144        Example:
1145            >>> Select().from_("tbl").select("x").order_by("x DESC").sql()
1146            'SELECT x FROM tbl ORDER BY x DESC'
1147
1148        Args:
1149            *expressions: the SQL code strings to parse.
1150                If a `Group` instance is passed, this is used as-is.
1151                If another `Expression` instance is passed, it will be wrapped in a `Order`.
1152            append: if `True`, add to any existing expressions.
1153                Otherwise, this flattens all the `Order` expression into a single expression.
1154            dialect: the dialect used to parse the input expression.
1155            copy: if `False`, modify this expression instance in-place.
1156            opts: other options to use to parse the input expressions.
1157
1158        Returns:
1159            The modified Select expression.
1160        """
1161        return _apply_child_list_builder(
1162            *expressions,
1163            instance=self,
1164            arg="order",
1165            append=append,
1166            copy=copy,
1167            prefix="ORDER BY",
1168            into=Order,
1169            dialect=dialect,
1170            **opts,
1171        )
1172
1173    @property
1174    def ctes(self) -> t.List[CTE]:
1175        """Returns a list of all the CTEs attached to this query."""
1176        with_ = self.args.get("with")
1177        return with_.expressions if with_ else []
1178
1179    @property
1180    def selects(self) -> t.List[Expression]:
1181        """Returns the query's projections."""
1182        raise NotImplementedError("Query objects must implement `selects`")
1183
1184    @property
1185    def named_selects(self) -> t.List[str]:
1186        """Returns the output names of the query's projections."""
1187        raise NotImplementedError("Query objects must implement `named_selects`")
1188
1189    def select(
1190        self: Q,
1191        *expressions: t.Optional[ExpOrStr],
1192        append: bool = True,
1193        dialect: DialectType = None,
1194        copy: bool = True,
1195        **opts,
1196    ) -> Q:
1197        """
1198        Append to or set the SELECT expressions.
1199
1200        Example:
1201            >>> Select().select("x", "y").sql()
1202            'SELECT x, y'
1203
1204        Args:
1205            *expressions: the SQL code strings to parse.
1206                If an `Expression` instance is passed, it will be used as-is.
1207            append: if `True`, add to any existing expressions.
1208                Otherwise, this resets the expressions.
1209            dialect: the dialect used to parse the input expressions.
1210            copy: if `False`, modify this expression instance in-place.
1211            opts: other options to use to parse the input expressions.
1212
1213        Returns:
1214            The modified Query expression.
1215        """
1216        raise NotImplementedError("Query objects must implement `select`")
1217
1218    def with_(
1219        self: Q,
1220        alias: ExpOrStr,
1221        as_: ExpOrStr,
1222        recursive: t.Optional[bool] = None,
1223        materialized: t.Optional[bool] = None,
1224        append: bool = True,
1225        dialect: DialectType = None,
1226        copy: bool = True,
1227        scalar: bool = False,
1228        **opts,
1229    ) -> Q:
1230        """
1231        Append to or set the common table expressions.
1232
1233        Example:
1234            >>> Select().with_("tbl2", as_="SELECT * FROM tbl").select("x").from_("tbl2").sql()
1235            'WITH tbl2 AS (SELECT * FROM tbl) SELECT x FROM tbl2'
1236
1237        Args:
1238            alias: the SQL code string to parse as the table name.
1239                If an `Expression` instance is passed, this is used as-is.
1240            as_: the SQL code string to parse as the table expression.
1241                If an `Expression` instance is passed, it will be used as-is.
1242            recursive: set the RECURSIVE part of the expression. Defaults to `False`.
1243            materialized: set the MATERIALIZED part of the expression.
1244            append: if `True`, add to any existing expressions.
1245                Otherwise, this resets the expressions.
1246            dialect: the dialect used to parse the input expression.
1247            copy: if `False`, modify this expression instance in-place.
1248            scalar: if `True`, this is a scalar common table expression.
1249            opts: other options to use to parse the input expressions.
1250
1251        Returns:
1252            The modified expression.
1253        """
1254        return _apply_cte_builder(
1255            self,
1256            alias,
1257            as_,
1258            recursive=recursive,
1259            materialized=materialized,
1260            append=append,
1261            dialect=dialect,
1262            copy=copy,
1263            scalar=scalar,
1264            **opts,
1265        )
1266
1267    def union(
1268        self, *expressions: ExpOrStr, distinct: bool = True, dialect: DialectType = None, **opts
1269    ) -> Union:
1270        """
1271        Builds a UNION expression.
1272
1273        Example:
1274            >>> import sqlglot
1275            >>> sqlglot.parse_one("SELECT * FROM foo").union("SELECT * FROM bla").sql()
1276            'SELECT * FROM foo UNION SELECT * FROM bla'
1277
1278        Args:
1279            expressions: the SQL code strings.
1280                If `Expression` instances are passed, they will be used as-is.
1281            distinct: set the DISTINCT flag if and only if this is true.
1282            dialect: the dialect used to parse the input expression.
1283            opts: other options to use to parse the input expressions.
1284
1285        Returns:
1286            The new Union expression.
1287        """
1288        return union(self, *expressions, distinct=distinct, dialect=dialect, **opts)
1289
1290    def intersect(
1291        self, *expressions: ExpOrStr, distinct: bool = True, dialect: DialectType = None, **opts
1292    ) -> Intersect:
1293        """
1294        Builds an INTERSECT expression.
1295
1296        Example:
1297            >>> import sqlglot
1298            >>> sqlglot.parse_one("SELECT * FROM foo").intersect("SELECT * FROM bla").sql()
1299            'SELECT * FROM foo INTERSECT SELECT * FROM bla'
1300
1301        Args:
1302            expressions: the SQL code strings.
1303                If `Expression` instances are passed, they will be used as-is.
1304            distinct: set the DISTINCT flag if and only if this is true.
1305            dialect: the dialect used to parse the input expression.
1306            opts: other options to use to parse the input expressions.
1307
1308        Returns:
1309            The new Intersect expression.
1310        """
1311        return intersect(self, *expressions, distinct=distinct, dialect=dialect, **opts)
1312
1313    def except_(
1314        self, *expressions: ExpOrStr, distinct: bool = True, dialect: DialectType = None, **opts
1315    ) -> Except:
1316        """
1317        Builds an EXCEPT expression.
1318
1319        Example:
1320            >>> import sqlglot
1321            >>> sqlglot.parse_one("SELECT * FROM foo").except_("SELECT * FROM bla").sql()
1322            'SELECT * FROM foo EXCEPT SELECT * FROM bla'
1323
1324        Args:
1325            expressions: the SQL code strings.
1326                If `Expression` instance are passed, they will be used as-is.
1327            distinct: set the DISTINCT flag if and only if this is true.
1328            dialect: the dialect used to parse the input expression.
1329            opts: other options to use to parse the input expressions.
1330
1331        Returns:
1332            The new Except expression.
1333        """
1334        return except_(self, *expressions, distinct=distinct, dialect=dialect, **opts)
1335
1336
1337class UDTF(DerivedTable):
1338    @property
1339    def selects(self) -> t.List[Expression]:
1340        alias = self.args.get("alias")
1341        return alias.columns if alias else []
1342
1343
1344class Cache(Expression):
1345    arg_types = {
1346        "this": True,
1347        "lazy": False,
1348        "options": False,
1349        "expression": False,
1350    }
1351
1352
1353class Uncache(Expression):
1354    arg_types = {"this": True, "exists": False}
1355
1356
1357class Refresh(Expression):
1358    pass
1359
1360
1361class DDL(Expression):
1362    @property
1363    def ctes(self) -> t.List[CTE]:
1364        """Returns a list of all the CTEs attached to this statement."""
1365        with_ = self.args.get("with")
1366        return with_.expressions if with_ else []
1367
1368    @property
1369    def selects(self) -> t.List[Expression]:
1370        """If this statement contains a query (e.g. a CTAS), this returns the query's projections."""
1371        return self.expression.selects if isinstance(self.expression, Query) else []
1372
1373    @property
1374    def named_selects(self) -> t.List[str]:
1375        """
1376        If this statement contains a query (e.g. a CTAS), this returns the output
1377        names of the query's projections.
1378        """
1379        return self.expression.named_selects if isinstance(self.expression, Query) else []
1380
1381
1382class DML(Expression):
1383    def returning(
1384        self,
1385        expression: ExpOrStr,
1386        dialect: DialectType = None,
1387        copy: bool = True,
1388        **opts,
1389    ) -> "Self":
1390        """
1391        Set the RETURNING expression. Not supported by all dialects.
1392
1393        Example:
1394            >>> delete("tbl").returning("*", dialect="postgres").sql()
1395            'DELETE FROM tbl RETURNING *'
1396
1397        Args:
1398            expression: the SQL code strings to parse.
1399                If an `Expression` instance is passed, it will be used as-is.
1400            dialect: the dialect used to parse the input expressions.
1401            copy: if `False`, modify this expression instance in-place.
1402            opts: other options to use to parse the input expressions.
1403
1404        Returns:
1405            Delete: the modified expression.
1406        """
1407        return _apply_builder(
1408            expression=expression,
1409            instance=self,
1410            arg="returning",
1411            prefix="RETURNING",
1412            dialect=dialect,
1413            copy=copy,
1414            into=Returning,
1415            **opts,
1416        )
1417
1418
1419class Create(DDL):
1420    arg_types = {
1421        "with": False,
1422        "this": True,
1423        "kind": True,
1424        "expression": False,
1425        "exists": False,
1426        "properties": False,
1427        "replace": False,
1428        "refresh": False,
1429        "unique": False,
1430        "indexes": False,
1431        "no_schema_binding": False,
1432        "begin": False,
1433        "end": False,
1434        "clone": False,
1435        "concurrently": False,
1436        "clustered": False,
1437    }
1438
1439    @property
1440    def kind(self) -> t.Optional[str]:
1441        kind = self.args.get("kind")
1442        return kind and kind.upper()
1443
1444
1445class SequenceProperties(Expression):
1446    arg_types = {
1447        "increment": False,
1448        "minvalue": False,
1449        "maxvalue": False,
1450        "cache": False,
1451        "start": False,
1452        "owned": False,
1453        "options": False,
1454    }
1455
1456
1457class TruncateTable(Expression):
1458    arg_types = {
1459        "expressions": True,
1460        "is_database": False,
1461        "exists": False,
1462        "only": False,
1463        "cluster": False,
1464        "identity": False,
1465        "option": False,
1466        "partition": False,
1467    }
1468
1469
1470# https://docs.snowflake.com/en/sql-reference/sql/create-clone
1471# https://cloud.google.com/bigquery/docs/reference/standard-sql/data-definition-language#create_table_clone_statement
1472# https://cloud.google.com/bigquery/docs/reference/standard-sql/data-definition-language#create_table_copy
1473class Clone(Expression):
1474    arg_types = {"this": True, "shallow": False, "copy": False}
1475
1476
1477class Describe(Expression):
1478    arg_types = {
1479        "this": True,
1480        "style": False,
1481        "kind": False,
1482        "expressions": False,
1483        "partition": False,
1484        "format": False,
1485    }
1486
1487
1488# https://duckdb.org/docs/sql/statements/attach.html#attach
1489class Attach(Expression):
1490    arg_types = {"this": True, "exists": False, "expressions": False}
1491
1492
1493# https://duckdb.org/docs/sql/statements/attach.html#detach
1494class Detach(Expression):
1495    arg_types = {"this": True, "exists": False}
1496
1497
1498# https://duckdb.org/docs/guides/meta/summarize.html
1499class Summarize(Expression):
1500    arg_types = {"this": True, "table": False}
1501
1502
1503class Kill(Expression):
1504    arg_types = {"this": True, "kind": False}
1505
1506
1507class Pragma(Expression):
1508    pass
1509
1510
1511class Declare(Expression):
1512    arg_types = {"expressions": True}
1513
1514
1515class DeclareItem(Expression):
1516    arg_types = {"this": True, "kind": True, "default": False}
1517
1518
1519class Set(Expression):
1520    arg_types = {"expressions": False, "unset": False, "tag": False}
1521
1522
1523class Heredoc(Expression):
1524    arg_types = {"this": True, "tag": False}
1525
1526
1527class SetItem(Expression):
1528    arg_types = {
1529        "this": False,
1530        "expressions": False,
1531        "kind": False,
1532        "collate": False,  # MySQL SET NAMES statement
1533        "global": False,
1534    }
1535
1536
1537class Show(Expression):
1538    arg_types = {
1539        "this": True,
1540        "history": False,
1541        "terse": False,
1542        "target": False,
1543        "offset": False,
1544        "starts_with": False,
1545        "limit": False,
1546        "from": False,
1547        "like": False,
1548        "where": False,
1549        "db": False,
1550        "scope": False,
1551        "scope_kind": False,
1552        "full": False,
1553        "mutex": False,
1554        "query": False,
1555        "channel": False,
1556        "global": False,
1557        "log": False,
1558        "position": False,
1559        "types": False,
1560        "privileges": False,
1561    }
1562
1563
1564class UserDefinedFunction(Expression):
1565    arg_types = {"this": True, "expressions": False, "wrapped": False}
1566
1567
1568class CharacterSet(Expression):
1569    arg_types = {"this": True, "default": False}
1570
1571
1572class RecursiveWithSearch(Expression):
1573    arg_types = {"kind": True, "this": True, "expression": True, "using": False}
1574
1575
1576class With(Expression):
1577    arg_types = {"expressions": True, "recursive": False, "search": False}
1578
1579    @property
1580    def recursive(self) -> bool:
1581        return bool(self.args.get("recursive"))
1582
1583
1584class WithinGroup(Expression):
1585    arg_types = {"this": True, "expression": False}
1586
1587
1588# clickhouse supports scalar ctes
1589# https://clickhouse.com/docs/en/sql-reference/statements/select/with
1590class CTE(DerivedTable):
1591    arg_types = {
1592        "this": True,
1593        "alias": True,
1594        "scalar": False,
1595        "materialized": False,
1596    }
1597
1598
1599class ProjectionDef(Expression):
1600    arg_types = {"this": True, "expression": True}
1601
1602
1603class TableAlias(Expression):
1604    arg_types = {"this": False, "columns": False}
1605
1606    @property
1607    def columns(self):
1608        return self.args.get("columns") or []
1609
1610
1611class BitString(Condition):
1612    pass
1613
1614
1615class HexString(Condition):
1616    arg_types = {"this": True, "is_integer": False}
1617
1618
1619class ByteString(Condition):
1620    pass
1621
1622
1623class RawString(Condition):
1624    pass
1625
1626
1627class UnicodeString(Condition):
1628    arg_types = {"this": True, "escape": False}
1629
1630
1631class Column(Condition):
1632    arg_types = {"this": True, "table": False, "db": False, "catalog": False, "join_mark": False}
1633
1634    @property
1635    def table(self) -> str:
1636        return self.text("table")
1637
1638    @property
1639    def db(self) -> str:
1640        return self.text("db")
1641
1642    @property
1643    def catalog(self) -> str:
1644        return self.text("catalog")
1645
1646    @property
1647    def output_name(self) -> str:
1648        return self.name
1649
1650    @property
1651    def parts(self) -> t.List[Identifier]:
1652        """Return the parts of a column in order catalog, db, table, name."""
1653        return [
1654            t.cast(Identifier, self.args[part])
1655            for part in ("catalog", "db", "table", "this")
1656            if self.args.get(part)
1657        ]
1658
1659    def to_dot(self) -> Dot | Identifier:
1660        """Converts the column into a dot expression."""
1661        parts = self.parts
1662        parent = self.parent
1663
1664        while parent:
1665            if isinstance(parent, Dot):
1666                parts.append(parent.expression)
1667            parent = parent.parent
1668
1669        return Dot.build(deepcopy(parts)) if len(parts) > 1 else parts[0]
1670
1671
1672class ColumnPosition(Expression):
1673    arg_types = {"this": False, "position": True}
1674
1675
1676class ColumnDef(Expression):
1677    arg_types = {
1678        "this": True,
1679        "kind": False,
1680        "constraints": False,
1681        "exists": False,
1682        "position": False,
1683        "default": False,
1684        "output": False,
1685    }
1686
1687    @property
1688    def constraints(self) -> t.List[ColumnConstraint]:
1689        return self.args.get("constraints") or []
1690
1691    @property
1692    def kind(self) -> t.Optional[DataType]:
1693        return self.args.get("kind")
1694
1695
1696class AlterColumn(Expression):
1697    arg_types = {
1698        "this": True,
1699        "dtype": False,
1700        "collate": False,
1701        "using": False,
1702        "default": False,
1703        "drop": False,
1704        "comment": False,
1705        "allow_null": False,
1706        "visible": False,
1707    }
1708
1709
1710# https://dev.mysql.com/doc/refman/8.0/en/invisible-indexes.html
1711class AlterIndex(Expression):
1712    arg_types = {"this": True, "visible": True}
1713
1714
1715# https://docs.aws.amazon.com/redshift/latest/dg/r_ALTER_TABLE.html
1716class AlterDistStyle(Expression):
1717    pass
1718
1719
1720class AlterSortKey(Expression):
1721    arg_types = {"this": False, "expressions": False, "compound": False}
1722
1723
1724class AlterSet(Expression):
1725    arg_types = {
1726        "expressions": False,
1727        "option": False,
1728        "tablespace": False,
1729        "access_method": False,
1730        "file_format": False,
1731        "copy_options": False,
1732        "tag": False,
1733        "location": False,
1734        "serde": False,
1735    }
1736
1737
1738class RenameColumn(Expression):
1739    arg_types = {"this": True, "to": True, "exists": False}
1740
1741
1742class AlterRename(Expression):
1743    pass
1744
1745
1746class SwapTable(Expression):
1747    pass
1748
1749
1750class Comment(Expression):
1751    arg_types = {
1752        "this": True,
1753        "kind": True,
1754        "expression": True,
1755        "exists": False,
1756        "materialized": False,
1757    }
1758
1759
1760class Comprehension(Expression):
1761    arg_types = {"this": True, "expression": True, "iterator": True, "condition": False}
1762
1763
1764# https://clickhouse.com/docs/en/engines/table-engines/mergetree-family/mergetree#mergetree-table-ttl
1765class MergeTreeTTLAction(Expression):
1766    arg_types = {
1767        "this": True,
1768        "delete": False,
1769        "recompress": False,
1770        "to_disk": False,
1771        "to_volume": False,
1772    }
1773
1774
1775# https://clickhouse.com/docs/en/engines/table-engines/mergetree-family/mergetree#mergetree-table-ttl
1776class MergeTreeTTL(Expression):
1777    arg_types = {
1778        "expressions": True,
1779        "where": False,
1780        "group": False,
1781        "aggregates": False,
1782    }
1783
1784
1785# https://dev.mysql.com/doc/refman/8.0/en/create-table.html
1786class IndexConstraintOption(Expression):
1787    arg_types = {
1788        "key_block_size": False,
1789        "using": False,
1790        "parser": False,
1791        "comment": False,
1792        "visible": False,
1793        "engine_attr": False,
1794        "secondary_engine_attr": False,
1795    }
1796
1797
1798class ColumnConstraint(Expression):
1799    arg_types = {"this": False, "kind": True}
1800
1801    @property
1802    def kind(self) -> ColumnConstraintKind:
1803        return self.args["kind"]
1804
1805
1806class ColumnConstraintKind(Expression):
1807    pass
1808
1809
1810class AutoIncrementColumnConstraint(ColumnConstraintKind):
1811    pass
1812
1813
1814class PeriodForSystemTimeConstraint(ColumnConstraintKind):
1815    arg_types = {"this": True, "expression": True}
1816
1817
1818class CaseSpecificColumnConstraint(ColumnConstraintKind):
1819    arg_types = {"not_": True}
1820
1821
1822class CharacterSetColumnConstraint(ColumnConstraintKind):
1823    arg_types = {"this": True}
1824
1825
1826class CheckColumnConstraint(ColumnConstraintKind):
1827    arg_types = {"this": True, "enforced": False}
1828
1829
1830class ClusteredColumnConstraint(ColumnConstraintKind):
1831    pass
1832
1833
1834class CollateColumnConstraint(ColumnConstraintKind):
1835    pass
1836
1837
1838class CommentColumnConstraint(ColumnConstraintKind):
1839    pass
1840
1841
1842class CompressColumnConstraint(ColumnConstraintKind):
1843    arg_types = {"this": False}
1844
1845
1846class DateFormatColumnConstraint(ColumnConstraintKind):
1847    arg_types = {"this": True}
1848
1849
1850class DefaultColumnConstraint(ColumnConstraintKind):
1851    pass
1852
1853
1854class EncodeColumnConstraint(ColumnConstraintKind):
1855    pass
1856
1857
1858# https://www.postgresql.org/docs/current/sql-createtable.html#SQL-CREATETABLE-EXCLUDE
1859class ExcludeColumnConstraint(ColumnConstraintKind):
1860    pass
1861
1862
1863class EphemeralColumnConstraint(ColumnConstraintKind):
1864    arg_types = {"this": False}
1865
1866
1867class WithOperator(Expression):
1868    arg_types = {"this": True, "op": True}
1869
1870
1871class GeneratedAsIdentityColumnConstraint(ColumnConstraintKind):
1872    # this: True -> ALWAYS, this: False -> BY DEFAULT
1873    arg_types = {
1874        "this": False,
1875        "expression": False,
1876        "on_null": False,
1877        "start": False,
1878        "increment": False,
1879        "minvalue": False,
1880        "maxvalue": False,
1881        "cycle": False,
1882    }
1883
1884
1885class GeneratedAsRowColumnConstraint(ColumnConstraintKind):
1886    arg_types = {"start": False, "hidden": False}
1887
1888
1889# https://dev.mysql.com/doc/refman/8.0/en/create-table.html
1890# https://github.com/ClickHouse/ClickHouse/blob/master/src/Parsers/ParserCreateQuery.h#L646
1891class IndexColumnConstraint(ColumnConstraintKind):
1892    arg_types = {
1893        "this": False,
1894        "expressions": False,
1895        "kind": False,
1896        "index_type": False,
1897        "options": False,
1898        "expression": False,  # Clickhouse
1899        "granularity": False,
1900    }
1901
1902
1903class InlineLengthColumnConstraint(ColumnConstraintKind):
1904    pass
1905
1906
1907class NonClusteredColumnConstraint(ColumnConstraintKind):
1908    pass
1909
1910
1911class NotForReplicationColumnConstraint(ColumnConstraintKind):
1912    arg_types = {}
1913
1914
1915# https://docs.snowflake.com/en/sql-reference/sql/create-table
1916class MaskingPolicyColumnConstraint(ColumnConstraintKind):
1917    arg_types = {"this": True, "expressions": False}
1918
1919
1920class NotNullColumnConstraint(ColumnConstraintKind):
1921    arg_types = {"allow_null": False}
1922
1923
1924# https://dev.mysql.com/doc/refman/5.7/en/timestamp-initialization.html
1925class OnUpdateColumnConstraint(ColumnConstraintKind):
1926    pass
1927
1928
1929# https://docs.snowflake.com/en/sql-reference/sql/create-external-table#optional-parameters
1930class TransformColumnConstraint(ColumnConstraintKind):
1931    pass
1932
1933
1934class PrimaryKeyColumnConstraint(ColumnConstraintKind):
1935    arg_types = {"desc": False}
1936
1937
1938class TitleColumnConstraint(ColumnConstraintKind):
1939    pass
1940
1941
1942class UniqueColumnConstraint(ColumnConstraintKind):
1943    arg_types = {"this": False, "index_type": False, "on_conflict": False, "nulls": False}
1944
1945
1946class UppercaseColumnConstraint(ColumnConstraintKind):
1947    arg_types: t.Dict[str, t.Any] = {}
1948
1949
1950# https://docs.risingwave.com/processing/watermarks#syntax
1951class WatermarkColumnConstraint(Expression):
1952    arg_types = {"this": True, "expression": True}
1953
1954
1955class PathColumnConstraint(ColumnConstraintKind):
1956    pass
1957
1958
1959# https://docs.snowflake.com/en/sql-reference/sql/create-table
1960class ProjectionPolicyColumnConstraint(ColumnConstraintKind):
1961    pass
1962
1963
1964# computed column expression
1965# https://learn.microsoft.com/en-us/sql/t-sql/statements/create-table-transact-sql?view=sql-server-ver16
1966class ComputedColumnConstraint(ColumnConstraintKind):
1967    arg_types = {"this": True, "persisted": False, "not_null": False}
1968
1969
1970class Constraint(Expression):
1971    arg_types = {"this": True, "expressions": True}
1972
1973
1974class Delete(DML):
1975    arg_types = {
1976        "with": False,
1977        "this": False,
1978        "using": False,
1979        "where": False,
1980        "returning": False,
1981        "limit": False,
1982        "tables": False,  # Multiple-Table Syntax (MySQL)
1983        "cluster": False,  # Clickhouse
1984    }
1985
1986    def delete(
1987        self,
1988        table: ExpOrStr,
1989        dialect: DialectType = None,
1990        copy: bool = True,
1991        **opts,
1992    ) -> Delete:
1993        """
1994        Create a DELETE expression or replace the table on an existing DELETE expression.
1995
1996        Example:
1997            >>> delete("tbl").sql()
1998            'DELETE FROM tbl'
1999
2000        Args:
2001            table: the table from which to delete.
2002            dialect: the dialect used to parse the input expression.
2003            copy: if `False`, modify this expression instance in-place.
2004            opts: other options to use to parse the input expressions.
2005
2006        Returns:
2007            Delete: the modified expression.
2008        """
2009        return _apply_builder(
2010            expression=table,
2011            instance=self,
2012            arg="this",
2013            dialect=dialect,
2014            into=Table,
2015            copy=copy,
2016            **opts,
2017        )
2018
2019    def where(
2020        self,
2021        *expressions: t.Optional[ExpOrStr],
2022        append: bool = True,
2023        dialect: DialectType = None,
2024        copy: bool = True,
2025        **opts,
2026    ) -> Delete:
2027        """
2028        Append to or set the WHERE expressions.
2029
2030        Example:
2031            >>> delete("tbl").where("x = 'a' OR x < 'b'").sql()
2032            "DELETE FROM tbl WHERE x = 'a' OR x < 'b'"
2033
2034        Args:
2035            *expressions: the SQL code strings to parse.
2036                If an `Expression` instance is passed, it will be used as-is.
2037                Multiple expressions are combined with an AND operator.
2038            append: if `True`, AND the new expressions to any existing expression.
2039                Otherwise, this resets the expression.
2040            dialect: the dialect used to parse the input expressions.
2041            copy: if `False`, modify this expression instance in-place.
2042            opts: other options to use to parse the input expressions.
2043
2044        Returns:
2045            Delete: the modified expression.
2046        """
2047        return _apply_conjunction_builder(
2048            *expressions,
2049            instance=self,
2050            arg="where",
2051            append=append,
2052            into=Where,
2053            dialect=dialect,
2054            copy=copy,
2055            **opts,
2056        )
2057
2058
2059class Drop(Expression):
2060    arg_types = {
2061        "this": False,
2062        "kind": False,
2063        "expressions": False,
2064        "exists": False,
2065        "temporary": False,
2066        "materialized": False,
2067        "cascade": False,
2068        "constraints": False,
2069        "purge": False,
2070        "cluster": False,
2071        "concurrently": False,
2072    }
2073
2074    @property
2075    def kind(self) -> t.Optional[str]:
2076        kind = self.args.get("kind")
2077        return kind and kind.upper()
2078
2079
2080# https://cloud.google.com/bigquery/docs/reference/standard-sql/export-statements
2081class Export(Expression):
2082    arg_types = {"this": True, "connection": False, "options": True}
2083
2084
2085class Filter(Expression):
2086    arg_types = {"this": True, "expression": True}
2087
2088
2089class Check(Expression):
2090    pass
2091
2092
2093class Changes(Expression):
2094    arg_types = {"information": True, "at_before": False, "end": False}
2095
2096
2097# https://docs.snowflake.com/en/sql-reference/constructs/connect-by
2098class Connect(Expression):
2099    arg_types = {"start": False, "connect": True, "nocycle": False}
2100
2101
2102class CopyParameter(Expression):
2103    arg_types = {"this": True, "expression": False, "expressions": False}
2104
2105
2106class Copy(DML):
2107    arg_types = {
2108        "this": True,
2109        "kind": True,
2110        "files": True,
2111        "credentials": False,
2112        "format": False,
2113        "params": False,
2114    }
2115
2116
2117class Credentials(Expression):
2118    arg_types = {
2119        "credentials": False,
2120        "encryption": False,
2121        "storage": False,
2122        "iam_role": False,
2123        "region": False,
2124    }
2125
2126
2127class Prior(Expression):
2128    pass
2129
2130
2131class Directory(Expression):
2132    # https://spark.apache.org/docs/3.0.0-preview/sql-ref-syntax-dml-insert-overwrite-directory-hive.html
2133    arg_types = {"this": True, "local": False, "row_format": False}
2134
2135
2136class ForeignKey(Expression):
2137    arg_types = {
2138        "expressions": False,
2139        "reference": False,
2140        "delete": False,
2141        "update": False,
2142    }
2143
2144
2145class ColumnPrefix(Expression):
2146    arg_types = {"this": True, "expression": True}
2147
2148
2149class PrimaryKey(Expression):
2150    arg_types = {"expressions": True, "options": False}
2151
2152
2153# https://www.postgresql.org/docs/9.1/sql-selectinto.html
2154# https://docs.aws.amazon.com/redshift/latest/dg/r_SELECT_INTO.html#r_SELECT_INTO-examples
2155class Into(Expression):
2156    arg_types = {
2157        "this": False,
2158        "temporary": False,
2159        "unlogged": False,
2160        "bulk_collect": False,
2161        "expressions": False,
2162    }
2163
2164
2165class From(Expression):
2166    @property
2167    def name(self) -> str:
2168        return self.this.name
2169
2170    @property
2171    def alias_or_name(self) -> str:
2172        return self.this.alias_or_name
2173
2174
2175class Having(Expression):
2176    pass
2177
2178
2179class Hint(Expression):
2180    arg_types = {"expressions": True}
2181
2182
2183class JoinHint(Expression):
2184    arg_types = {"this": True, "expressions": True}
2185
2186
2187class Identifier(Expression):
2188    arg_types = {"this": True, "quoted": False, "global": False, "temporary": False}
2189
2190    @property
2191    def quoted(self) -> bool:
2192        return bool(self.args.get("quoted"))
2193
2194    @property
2195    def hashable_args(self) -> t.Any:
2196        return (self.this, self.quoted)
2197
2198    @property
2199    def output_name(self) -> str:
2200        return self.name
2201
2202
2203# https://www.postgresql.org/docs/current/indexes-opclass.html
2204class Opclass(Expression):
2205    arg_types = {"this": True, "expression": True}
2206
2207
2208class Index(Expression):
2209    arg_types = {
2210        "this": False,
2211        "table": False,
2212        "unique": False,
2213        "primary": False,
2214        "amp": False,  # teradata
2215        "params": False,
2216    }
2217
2218
2219class IndexParameters(Expression):
2220    arg_types = {
2221        "using": False,
2222        "include": False,
2223        "columns": False,
2224        "with_storage": False,
2225        "partition_by": False,
2226        "tablespace": False,
2227        "where": False,
2228        "on": False,
2229    }
2230
2231
2232class Insert(DDL, DML):
2233    arg_types = {
2234        "hint": False,
2235        "with": False,
2236        "is_function": False,
2237        "this": False,
2238        "expression": False,
2239        "conflict": False,
2240        "returning": False,
2241        "overwrite": False,
2242        "exists": False,
2243        "alternative": False,
2244        "where": False,
2245        "ignore": False,
2246        "by_name": False,
2247        "stored": False,
2248        "partition": False,
2249        "settings": False,
2250        "source": False,
2251    }
2252
2253    def with_(
2254        self,
2255        alias: ExpOrStr,
2256        as_: ExpOrStr,
2257        recursive: t.Optional[bool] = None,
2258        materialized: t.Optional[bool] = None,
2259        append: bool = True,
2260        dialect: DialectType = None,
2261        copy: bool = True,
2262        **opts,
2263    ) -> Insert:
2264        """
2265        Append to or set the common table expressions.
2266
2267        Example:
2268            >>> insert("SELECT x FROM cte", "t").with_("cte", as_="SELECT * FROM tbl").sql()
2269            'WITH cte AS (SELECT * FROM tbl) INSERT INTO t SELECT x FROM cte'
2270
2271        Args:
2272            alias: the SQL code string to parse as the table name.
2273                If an `Expression` instance is passed, this is used as-is.
2274            as_: the SQL code string to parse as the table expression.
2275                If an `Expression` instance is passed, it will be used as-is.
2276            recursive: set the RECURSIVE part of the expression. Defaults to `False`.
2277            materialized: set the MATERIALIZED part of the expression.
2278            append: if `True`, add to any existing expressions.
2279                Otherwise, this resets the expressions.
2280            dialect: the dialect used to parse the input expression.
2281            copy: if `False`, modify this expression instance in-place.
2282            opts: other options to use to parse the input expressions.
2283
2284        Returns:
2285            The modified expression.
2286        """
2287        return _apply_cte_builder(
2288            self,
2289            alias,
2290            as_,
2291            recursive=recursive,
2292            materialized=materialized,
2293            append=append,
2294            dialect=dialect,
2295            copy=copy,
2296            **opts,
2297        )
2298
2299
2300class ConditionalInsert(Expression):
2301    arg_types = {"this": True, "expression": False, "else_": False}
2302
2303
2304class MultitableInserts(Expression):
2305    arg_types = {"expressions": True, "kind": True, "source": True}
2306
2307
2308class OnConflict(Expression):
2309    arg_types = {
2310        "duplicate": False,
2311        "expressions": False,
2312        "action": False,
2313        "conflict_keys": False,
2314        "constraint": False,
2315        "where": False,
2316    }
2317
2318
2319class OnCondition(Expression):
2320    arg_types = {"error": False, "empty": False, "null": False}
2321
2322
2323class Returning(Expression):
2324    arg_types = {"expressions": True, "into": False}
2325
2326
2327# https://dev.mysql.com/doc/refman/8.0/en/charset-introducer.html
2328class Introducer(Expression):
2329    arg_types = {"this": True, "expression": True}
2330
2331
2332# national char, like n'utf8'
2333class National(Expression):
2334    pass
2335
2336
2337class LoadData(Expression):
2338    arg_types = {
2339        "this": True,
2340        "local": False,
2341        "overwrite": False,
2342        "inpath": True,
2343        "partition": False,
2344        "input_format": False,
2345        "serde": False,
2346    }
2347
2348
2349class Partition(Expression):
2350    arg_types = {"expressions": True, "subpartition": False}
2351
2352
2353class PartitionRange(Expression):
2354    arg_types = {"this": True, "expression": True}
2355
2356
2357# https://clickhouse.com/docs/en/sql-reference/statements/alter/partition#how-to-set-partition-expression
2358class PartitionId(Expression):
2359    pass
2360
2361
2362class Fetch(Expression):
2363    arg_types = {
2364        "direction": False,
2365        "count": False,
2366        "limit_options": False,
2367    }
2368
2369
2370class Grant(Expression):
2371    arg_types = {
2372        "privileges": True,
2373        "kind": False,
2374        "securable": True,
2375        "principals": True,
2376        "grant_option": False,
2377    }
2378
2379
2380class Group(Expression):
2381    arg_types = {
2382        "expressions": False,
2383        "grouping_sets": False,
2384        "cube": False,
2385        "rollup": False,
2386        "totals": False,
2387        "all": False,
2388    }
2389
2390
2391class Cube(Expression):
2392    arg_types = {"expressions": False}
2393
2394
2395class Rollup(Expression):
2396    arg_types = {"expressions": False}
2397
2398
2399class GroupingSets(Expression):
2400    arg_types = {"expressions": True}
2401
2402
2403class Lambda(Expression):
2404    arg_types = {"this": True, "expressions": True}
2405
2406
2407class Limit(Expression):
2408    arg_types = {
2409        "this": False,
2410        "expression": True,
2411        "offset": False,
2412        "limit_options": False,
2413        "expressions": False,
2414    }
2415
2416
2417class LimitOptions(Expression):
2418    arg_types = {
2419        "percent": False,
2420        "rows": False,
2421        "with_ties": False,
2422    }
2423
2424
2425class Literal(Condition):
2426    arg_types = {"this": True, "is_string": True}
2427
2428    @property
2429    def hashable_args(self) -> t.Any:
2430        return (self.this, self.args.get("is_string"))
2431
2432    @classmethod
2433    def number(cls, number) -> Literal:
2434        return cls(this=str(number), is_string=False)
2435
2436    @classmethod
2437    def string(cls, string) -> Literal:
2438        return cls(this=str(string), is_string=True)
2439
2440    @property
2441    def output_name(self) -> str:
2442        return self.name
2443
2444    def to_py(self) -> int | str | Decimal:
2445        if self.is_number:
2446            try:
2447                return int(self.this)
2448            except ValueError:
2449                return Decimal(self.this)
2450        return self.this
2451
2452
2453class Join(Expression):
2454    arg_types = {
2455        "this": True,
2456        "on": False,
2457        "side": False,
2458        "kind": False,
2459        "using": False,
2460        "method": False,
2461        "global": False,
2462        "hint": False,
2463        "match_condition": False,  # Snowflake
2464        "expressions": False,
2465    }
2466
2467    @property
2468    def method(self) -> str:
2469        return self.text("method").upper()
2470
2471    @property
2472    def kind(self) -> str:
2473        return self.text("kind").upper()
2474
2475    @property
2476    def side(self) -> str:
2477        return self.text("side").upper()
2478
2479    @property
2480    def hint(self) -> str:
2481        return self.text("hint").upper()
2482
2483    @property
2484    def alias_or_name(self) -> str:
2485        return self.this.alias_or_name
2486
2487    @property
2488    def is_semi_or_anti_join(self) -> bool:
2489        return self.kind in ("SEMI", "ANTI")
2490
2491    def on(
2492        self,
2493        *expressions: t.Optional[ExpOrStr],
2494        append: bool = True,
2495        dialect: DialectType = None,
2496        copy: bool = True,
2497        **opts,
2498    ) -> Join:
2499        """
2500        Append to or set the ON expressions.
2501
2502        Example:
2503            >>> import sqlglot
2504            >>> sqlglot.parse_one("JOIN x", into=Join).on("y = 1").sql()
2505            'JOIN x ON y = 1'
2506
2507        Args:
2508            *expressions: the SQL code strings to parse.
2509                If an `Expression` instance is passed, it will be used as-is.
2510                Multiple expressions are combined with an AND operator.
2511            append: if `True`, AND the new expressions to any existing expression.
2512                Otherwise, this resets the expression.
2513            dialect: the dialect used to parse the input expressions.
2514            copy: if `False`, modify this expression instance in-place.
2515            opts: other options to use to parse the input expressions.
2516
2517        Returns:
2518            The modified Join expression.
2519        """
2520        join = _apply_conjunction_builder(
2521            *expressions,
2522            instance=self,
2523            arg="on",
2524            append=append,
2525            dialect=dialect,
2526            copy=copy,
2527            **opts,
2528        )
2529
2530        if join.kind == "CROSS":
2531            join.set("kind", None)
2532
2533        return join
2534
2535    def using(
2536        self,
2537        *expressions: t.Optional[ExpOrStr],
2538        append: bool = True,
2539        dialect: DialectType = None,
2540        copy: bool = True,
2541        **opts,
2542    ) -> Join:
2543        """
2544        Append to or set the USING expressions.
2545
2546        Example:
2547            >>> import sqlglot
2548            >>> sqlglot.parse_one("JOIN x", into=Join).using("foo", "bla").sql()
2549            'JOIN x USING (foo, bla)'
2550
2551        Args:
2552            *expressions: the SQL code strings to parse.
2553                If an `Expression` instance is passed, it will be used as-is.
2554            append: if `True`, concatenate the new expressions to the existing "using" list.
2555                Otherwise, this resets the expression.
2556            dialect: the dialect used to parse the input expressions.
2557            copy: if `False`, modify this expression instance in-place.
2558            opts: other options to use to parse the input expressions.
2559
2560        Returns:
2561            The modified Join expression.
2562        """
2563        join = _apply_list_builder(
2564            *expressions,
2565            instance=self,
2566            arg="using",
2567            append=append,
2568            dialect=dialect,
2569            copy=copy,
2570            **opts,
2571        )
2572
2573        if join.kind == "CROSS":
2574            join.set("kind", None)
2575
2576        return join
2577
2578
2579class Lateral(UDTF):
2580    arg_types = {
2581        "this": True,
2582        "view": False,
2583        "outer": False,
2584        "alias": False,
2585        "cross_apply": False,  # True -> CROSS APPLY, False -> OUTER APPLY
2586    }
2587
2588
2589class MatchRecognizeMeasure(Expression):
2590    arg_types = {
2591        "this": True,
2592        "window_frame": False,
2593    }
2594
2595
2596class MatchRecognize(Expression):
2597    arg_types = {
2598        "partition_by": False,
2599        "order": False,
2600        "measures": False,
2601        "rows": False,
2602        "after": False,
2603        "pattern": False,
2604        "define": False,
2605        "alias": False,
2606    }
2607
2608
2609# Clickhouse FROM FINAL modifier
2610# https://clickhouse.com/docs/en/sql-reference/statements/select/from/#final-modifier
2611class Final(Expression):
2612    pass
2613
2614
2615class Offset(Expression):
2616    arg_types = {"this": False, "expression": True, "expressions": False}
2617
2618
2619class Order(Expression):
2620    arg_types = {"this": False, "expressions": True, "siblings": False}
2621
2622
2623# https://clickhouse.com/docs/en/sql-reference/statements/select/order-by#order-by-expr-with-fill-modifier
2624class WithFill(Expression):
2625    arg_types = {
2626        "from": False,
2627        "to": False,
2628        "step": False,
2629        "interpolate": False,
2630    }
2631
2632
2633# hive specific sorts
2634# https://cwiki.apache.org/confluence/display/Hive/LanguageManual+SortBy
2635class Cluster(Order):
2636    pass
2637
2638
2639class Distribute(Order):
2640    pass
2641
2642
2643class Sort(Order):
2644    pass
2645
2646
2647class Ordered(Expression):
2648    arg_types = {"this": True, "desc": False, "nulls_first": True, "with_fill": False}
2649
2650
2651class Property(Expression):
2652    arg_types = {"this": True, "value": True}
2653
2654
2655class GrantPrivilege(Expression):
2656    arg_types = {"this": True, "expressions": False}
2657
2658
2659class GrantPrincipal(Expression):
2660    arg_types = {"this": True, "kind": False}
2661
2662
2663class AllowedValuesProperty(Expression):
2664    arg_types = {"expressions": True}
2665
2666
2667class AlgorithmProperty(Property):
2668    arg_types = {"this": True}
2669
2670
2671class AutoIncrementProperty(Property):
2672    arg_types = {"this": True}
2673
2674
2675# https://docs.aws.amazon.com/prescriptive-guidance/latest/materialized-views-redshift/refreshing-materialized-views.html
2676class AutoRefreshProperty(Property):
2677    arg_types = {"this": True}
2678
2679
2680class BackupProperty(Property):
2681    arg_types = {"this": True}
2682
2683
2684class BlockCompressionProperty(Property):
2685    arg_types = {
2686        "autotemp": False,
2687        "always": False,
2688        "default": False,
2689        "manual": False,
2690        "never": False,
2691    }
2692
2693
2694class CharacterSetProperty(Property):
2695    arg_types = {"this": True, "default": True}
2696
2697
2698class ChecksumProperty(Property):
2699    arg_types = {"on": False, "default": False}
2700
2701
2702class CollateProperty(Property):
2703    arg_types = {"this": True, "default": False}
2704
2705
2706class CopyGrantsProperty(Property):
2707    arg_types = {}
2708
2709
2710class DataBlocksizeProperty(Property):
2711    arg_types = {
2712        "size": False,
2713        "units": False,
2714        "minimum": False,
2715        "maximum": False,
2716        "default": False,
2717    }
2718
2719
2720class DataDeletionProperty(Property):
2721    arg_types = {"on": True, "filter_col": False, "retention_period": False}
2722
2723
2724class DefinerProperty(Property):
2725    arg_types = {"this": True}
2726
2727
2728class DistKeyProperty(Property):
2729    arg_types = {"this": True}
2730
2731
2732# https://docs.starrocks.io/docs/sql-reference/sql-statements/data-definition/CREATE_TABLE/#distribution_desc
2733# https://doris.apache.org/docs/sql-manual/sql-statements/Data-Definition-Statements/Create/CREATE-TABLE?_highlight=create&_highlight=table#distribution_desc
2734class DistributedByProperty(Property):
2735    arg_types = {"expressions": False, "kind": True, "buckets": False, "order": False}
2736
2737
2738class DistStyleProperty(Property):
2739    arg_types = {"this": True}
2740
2741
2742class DuplicateKeyProperty(Property):
2743    arg_types = {"expressions": True}
2744
2745
2746class EngineProperty(Property):
2747    arg_types = {"this": True}
2748
2749
2750class HeapProperty(Property):
2751    arg_types = {}
2752
2753
2754class ToTableProperty(Property):
2755    arg_types = {"this": True}
2756
2757
2758class ExecuteAsProperty(Property):
2759    arg_types = {"this": True}
2760
2761
2762class ExternalProperty(Property):
2763    arg_types = {"this": False}
2764
2765
2766class FallbackProperty(Property):
2767    arg_types = {"no": True, "protection": False}
2768
2769
2770class FileFormatProperty(Property):
2771    arg_types = {"this": True}
2772
2773
2774class FreespaceProperty(Property):
2775    arg_types = {"this": True, "percent": False}
2776
2777
2778class GlobalProperty(Property):
2779    arg_types = {}
2780
2781
2782class IcebergProperty(Property):
2783    arg_types = {}
2784
2785
2786class InheritsProperty(Property):
2787    arg_types = {"expressions": True}
2788
2789
2790class InputModelProperty(Property):
2791    arg_types = {"this": True}
2792
2793
2794class OutputModelProperty(Property):
2795    arg_types = {"this": True}
2796
2797
2798class IsolatedLoadingProperty(Property):
2799    arg_types = {"no": False, "concurrent": False, "target": False}
2800
2801
2802class JournalProperty(Property):
2803    arg_types = {
2804        "no": False,
2805        "dual": False,
2806        "before": False,
2807        "local": False,
2808        "after": False,
2809    }
2810
2811
2812class LanguageProperty(Property):
2813    arg_types = {"this": True}
2814
2815
2816# spark ddl
2817class ClusteredByProperty(Property):
2818    arg_types = {"expressions": True, "sorted_by": False, "buckets": True}
2819
2820
2821class DictProperty(Property):
2822    arg_types = {"this": True, "kind": True, "settings": False}
2823
2824
2825class DictSubProperty(Property):
2826    pass
2827
2828
2829class DictRange(Property):
2830    arg_types = {"this": True, "min": True, "max": True}
2831
2832
2833class DynamicProperty(Property):
2834    arg_types = {}
2835
2836
2837# Clickhouse CREATE ... ON CLUSTER modifier
2838# https://clickhouse.com/docs/en/sql-reference/distributed-ddl
2839class OnCluster(Property):
2840    arg_types = {"this": True}
2841
2842
2843# Clickhouse EMPTY table "property"
2844class EmptyProperty(Property):
2845    arg_types = {}
2846
2847
2848class LikeProperty(Property):
2849    arg_types = {"this": True, "expressions": False}
2850
2851
2852class LocationProperty(Property):
2853    arg_types = {"this": True}
2854
2855
2856class LockProperty(Property):
2857    arg_types = {"this": True}
2858
2859
2860class LockingProperty(Property):
2861    arg_types = {
2862        "this": False,
2863        "kind": True,
2864        "for_or_in": False,
2865        "lock_type": True,
2866        "override": False,
2867    }
2868
2869
2870class LogProperty(Property):
2871    arg_types = {"no": True}
2872
2873
2874class MaterializedProperty(Property):
2875    arg_types = {"this": False}
2876
2877
2878class MergeBlockRatioProperty(Property):
2879    arg_types = {"this": False, "no": False, "default": False, "percent": False}
2880
2881
2882class NoPrimaryIndexProperty(Property):
2883    arg_types = {}
2884
2885
2886class OnProperty(Property):
2887    arg_types = {"this": True}
2888
2889
2890class OnCommitProperty(Property):
2891    arg_types = {"delete": False}
2892
2893
2894class PartitionedByProperty(Property):
2895    arg_types = {"this": True}
2896
2897
2898# https://docs.starrocks.io/docs/sql-reference/sql-statements/table_bucket_part_index/CREATE_TABLE/
2899class PartitionByRangeProperty(Property):
2900    arg_types = {"partition_expressions": True, "create_expressions": True}
2901
2902
2903# https://docs.starrocks.io/docs/table_design/data_distribution/#range-partitioning
2904class PartitionByRangePropertyDynamic(Expression):
2905    arg_types = {"this": False, "start": True, "end": True, "every": True}
2906
2907
2908# https://docs.starrocks.io/docs/sql-reference/sql-statements/table_bucket_part_index/CREATE_TABLE/
2909class UniqueKeyProperty(Property):
2910    arg_types = {"expressions": True}
2911
2912
2913# https://www.postgresql.org/docs/current/sql-createtable.html
2914class PartitionBoundSpec(Expression):
2915    # this -> IN / MODULUS, expression -> REMAINDER, from_expressions -> FROM (...), to_expressions -> TO (...)
2916    arg_types = {
2917        "this": False,
2918        "expression": False,
2919        "from_expressions": False,
2920        "to_expressions": False,
2921    }
2922
2923
2924class PartitionedOfProperty(Property):
2925    # this -> parent_table (schema), expression -> FOR VALUES ... / DEFAULT
2926    arg_types = {"this": True, "expression": True}
2927
2928
2929class StreamingTableProperty(Property):
2930    arg_types = {}
2931
2932
2933class RemoteWithConnectionModelProperty(Property):
2934    arg_types = {"this": True}
2935
2936
2937class ReturnsProperty(Property):
2938    arg_types = {"this": False, "is_table": False, "table": False, "null": False}
2939
2940
2941class StrictProperty(Property):
2942    arg_types = {}
2943
2944
2945class RowFormatProperty(Property):
2946    arg_types = {"this": True}
2947
2948
2949class RowFormatDelimitedProperty(Property):
2950    # https://cwiki.apache.org/confluence/display/hive/languagemanual+dml
2951    arg_types = {
2952        "fields": False,
2953        "escaped": False,
2954        "collection_items": False,
2955        "map_keys": False,
2956        "lines": False,
2957        "null": False,
2958        "serde": False,
2959    }
2960
2961
2962class RowFormatSerdeProperty(Property):
2963    arg_types = {"this": True, "serde_properties": False}
2964
2965
2966# https://spark.apache.org/docs/3.1.2/sql-ref-syntax-qry-select-transform.html
2967class QueryTransform(Expression):
2968    arg_types = {
2969        "expressions": True,
2970        "command_script": True,
2971        "schema": False,
2972        "row_format_before": False,
2973        "record_writer": False,
2974        "row_format_after": False,
2975        "record_reader": False,
2976    }
2977
2978
2979class SampleProperty(Property):
2980    arg_types = {"this": True}
2981
2982
2983# https://prestodb.io/docs/current/sql/create-view.html#synopsis
2984class SecurityProperty(Property):
2985    arg_types = {"this": True}
2986
2987
2988class SchemaCommentProperty(Property):
2989    arg_types = {"this": True}
2990
2991
2992class SerdeProperties(Property):
2993    arg_types = {"expressions": True, "with": False}
2994
2995
2996class SetProperty(Property):
2997    arg_types = {"multi": True}
2998
2999
3000class SharingProperty(Property):
3001    arg_types = {"this": False}
3002
3003
3004class SetConfigProperty(Property):
3005    arg_types = {"this": True}
3006
3007
3008class SettingsProperty(Property):
3009    arg_types = {"expressions": True}
3010
3011
3012class SortKeyProperty(Property):
3013    arg_types = {"this": True, "compound": False}
3014
3015
3016class SqlReadWriteProperty(Property):
3017    arg_types = {"this": True}
3018
3019
3020class SqlSecurityProperty(Property):
3021    arg_types = {"definer": True}
3022
3023
3024class StabilityProperty(Property):
3025    arg_types = {"this": True}
3026
3027
3028class StorageHandlerProperty(Property):
3029    arg_types = {"this": True}
3030
3031
3032class TemporaryProperty(Property):
3033    arg_types = {"this": False}
3034
3035
3036class SecureProperty(Property):
3037    arg_types = {}
3038
3039
3040# https://docs.snowflake.com/en/sql-reference/sql/create-table
3041class Tags(ColumnConstraintKind, Property):
3042    arg_types = {"expressions": True}
3043
3044
3045class TransformModelProperty(Property):
3046    arg_types = {"expressions": True}
3047
3048
3049class TransientProperty(Property):
3050    arg_types = {"this": False}
3051
3052
3053class UnloggedProperty(Property):
3054    arg_types = {}
3055
3056
3057# https://learn.microsoft.com/en-us/sql/t-sql/statements/create-view-transact-sql?view=sql-server-ver16
3058class ViewAttributeProperty(Property):
3059    arg_types = {"this": True}
3060
3061
3062class VolatileProperty(Property):
3063    arg_types = {"this": False}
3064
3065
3066class WithDataProperty(Property):
3067    arg_types = {"no": True, "statistics": False}
3068
3069
3070class WithJournalTableProperty(Property):
3071    arg_types = {"this": True}
3072
3073
3074class WithSchemaBindingProperty(Property):
3075    arg_types = {"this": True}
3076
3077
3078class WithSystemVersioningProperty(Property):
3079    arg_types = {
3080        "on": False,
3081        "this": False,
3082        "data_consistency": False,
3083        "retention_period": False,
3084        "with": True,
3085    }
3086
3087
3088class WithProcedureOptions(Property):
3089    arg_types = {"expressions": True}
3090
3091
3092class EncodeProperty(Property):
3093    arg_types = {"this": True, "properties": False, "key": False}
3094
3095
3096class IncludeProperty(Property):
3097    arg_types = {"this": True, "alias": False, "column_def": False}
3098
3099
3100class ForceProperty(Property):
3101    arg_types = {}
3102
3103
3104class Properties(Expression):
3105    arg_types = {"expressions": True}
3106
3107    NAME_TO_PROPERTY = {
3108        "ALGORITHM": AlgorithmProperty,
3109        "AUTO_INCREMENT": AutoIncrementProperty,
3110        "CHARACTER SET": CharacterSetProperty,
3111        "CLUSTERED_BY": ClusteredByProperty,
3112        "COLLATE": CollateProperty,
3113        "COMMENT": SchemaCommentProperty,
3114        "DEFINER": DefinerProperty,
3115        "DISTKEY": DistKeyProperty,
3116        "DISTRIBUTED_BY": DistributedByProperty,
3117        "DISTSTYLE": DistStyleProperty,
3118        "ENGINE": EngineProperty,
3119        "EXECUTE AS": ExecuteAsProperty,
3120        "FORMAT": FileFormatProperty,
3121        "LANGUAGE": LanguageProperty,
3122        "LOCATION": LocationProperty,
3123        "LOCK": LockProperty,
3124        "PARTITIONED_BY": PartitionedByProperty,
3125        "RETURNS": ReturnsProperty,
3126        "ROW_FORMAT": RowFormatProperty,
3127        "SORTKEY": SortKeyProperty,
3128        "ENCODE": EncodeProperty,
3129        "INCLUDE": IncludeProperty,
3130    }
3131
3132    PROPERTY_TO_NAME = {v: k for k, v in NAME_TO_PROPERTY.items()}
3133
3134    # CREATE property locations
3135    # Form: schema specified
3136    #   create [POST_CREATE]
3137    #     table a [POST_NAME]
3138    #     (b int) [POST_SCHEMA]
3139    #     with ([POST_WITH])
3140    #     index (b) [POST_INDEX]
3141    #
3142    # Form: alias selection
3143    #   create [POST_CREATE]
3144    #     table a [POST_NAME]
3145    #     as [POST_ALIAS] (select * from b) [POST_EXPRESSION]
3146    #     index (c) [POST_INDEX]
3147    class Location(AutoName):
3148        POST_CREATE = auto()
3149        POST_NAME = auto()
3150        POST_SCHEMA = auto()
3151        POST_WITH = auto()
3152        POST_ALIAS = auto()
3153        POST_EXPRESSION = auto()
3154        POST_INDEX = auto()
3155        UNSUPPORTED = auto()
3156
3157    @classmethod
3158    def from_dict(cls, properties_dict: t.Dict) -> Properties:
3159        expressions = []
3160        for key, value in properties_dict.items():
3161            property_cls = cls.NAME_TO_PROPERTY.get(key.upper())
3162            if property_cls:
3163                expressions.append(property_cls(this=convert(value)))
3164            else:
3165                expressions.append(Property(this=Literal.string(key), value=convert(value)))
3166
3167        return cls(expressions=expressions)
3168
3169
3170class Qualify(Expression):
3171    pass
3172
3173
3174class InputOutputFormat(Expression):
3175    arg_types = {"input_format": False, "output_format": False}
3176
3177
3178# https://www.ibm.com/docs/en/ias?topic=procedures-return-statement-in-sql
3179class Return(Expression):
3180    pass
3181
3182
3183class Reference(Expression):
3184    arg_types = {"this": True, "expressions": False, "options": False}
3185
3186
3187class Tuple(Expression):
3188    arg_types = {"expressions": False}
3189
3190    def isin(
3191        self,
3192        *expressions: t.Any,
3193        query: t.Optional[ExpOrStr] = None,
3194        unnest: t.Optional[ExpOrStr] | t.Collection[ExpOrStr] = None,
3195        copy: bool = True,
3196        **opts,
3197    ) -> In:
3198        return In(
3199            this=maybe_copy(self, copy),
3200            expressions=[convert(e, copy=copy) for e in expressions],
3201            query=maybe_parse(query, copy=copy, **opts) if query else None,
3202            unnest=(
3203                Unnest(
3204                    expressions=[
3205                        maybe_parse(t.cast(ExpOrStr, e), copy=copy, **opts)
3206                        for e in ensure_list(unnest)
3207                    ]
3208                )
3209                if unnest
3210                else None
3211            ),
3212        )
3213
3214
3215QUERY_MODIFIERS = {
3216    "match": False,
3217    "laterals": False,
3218    "joins": False,
3219    "connect": False,
3220    "pivots": False,
3221    "prewhere": False,
3222    "where": False,
3223    "group": False,
3224    "having": False,
3225    "qualify": False,
3226    "windows": False,
3227    "distribute": False,
3228    "sort": False,
3229    "cluster": False,
3230    "order": False,
3231    "limit": False,
3232    "offset": False,
3233    "locks": False,
3234    "sample": False,
3235    "settings": False,
3236    "format": False,
3237    "options": False,
3238}
3239
3240
3241# https://learn.microsoft.com/en-us/sql/t-sql/queries/option-clause-transact-sql?view=sql-server-ver16
3242# https://learn.microsoft.com/en-us/sql/t-sql/queries/hints-transact-sql-query?view=sql-server-ver16
3243class QueryOption(Expression):
3244    arg_types = {"this": True, "expression": False}
3245
3246
3247# https://learn.microsoft.com/en-us/sql/t-sql/queries/hints-transact-sql-table?view=sql-server-ver16
3248class WithTableHint(Expression):
3249    arg_types = {"expressions": True}
3250
3251
3252# https://dev.mysql.com/doc/refman/8.0/en/index-hints.html
3253class IndexTableHint(Expression):
3254    arg_types = {"this": True, "expressions": False, "target": False}
3255
3256
3257# https://docs.snowflake.com/en/sql-reference/constructs/at-before
3258class HistoricalData(Expression):
3259    arg_types = {"this": True, "kind": True, "expression": True}
3260
3261
3262# https://docs.snowflake.com/en/sql-reference/sql/put
3263class Put(Expression):
3264    arg_types = {"this": True, "target": True, "properties": False}
3265
3266
3267class Table(Expression):
3268    arg_types = {
3269        "this": False,
3270        "alias": False,
3271        "db": False,
3272        "catalog": False,
3273        "laterals": False,
3274        "joins": False,
3275        "pivots": False,
3276        "hints": False,
3277        "system_time": False,
3278        "version": False,
3279        "format": False,
3280        "pattern": False,
3281        "ordinality": False,
3282        "when": False,
3283        "only": False,
3284        "partition": False,
3285        "changes": False,
3286        "rows_from": False,
3287        "sample": False,
3288    }
3289
3290    @property
3291    def name(self) -> str:
3292        if not self.this or isinstance(self.this, Func):
3293            return ""
3294        return self.this.name
3295
3296    @property
3297    def db(self) -> str:
3298        return self.text("db")
3299
3300    @property
3301    def catalog(self) -> str:
3302        return self.text("catalog")
3303
3304    @property
3305    def selects(self) -> t.List[Expression]:
3306        return []
3307
3308    @property
3309    def named_selects(self) -> t.List[str]:
3310        return []
3311
3312    @property
3313    def parts(self) -> t.List[Expression]:
3314        """Return the parts of a table in order catalog, db, table."""
3315        parts: t.List[Expression] = []
3316
3317        for arg in ("catalog", "db", "this"):
3318            part = self.args.get(arg)
3319
3320            if isinstance(part, Dot):
3321                parts.extend(part.flatten())
3322            elif isinstance(part, Expression):
3323                parts.append(part)
3324
3325        return parts
3326
3327    def to_column(self, copy: bool = True) -> Expression:
3328        parts = self.parts
3329        last_part = parts[-1]
3330
3331        if isinstance(last_part, Identifier):
3332            col: Expression = column(*reversed(parts[0:4]), fields=parts[4:], copy=copy)  # type: ignore
3333        else:
3334            # This branch will be reached if a function or array is wrapped in a `Table`
3335            col = last_part
3336
3337        alias = self.args.get("alias")
3338        if alias:
3339            col = alias_(col, alias.this, copy=copy)
3340
3341        return col
3342
3343
3344class SetOperation(Query):
3345    arg_types = {
3346        "with": False,
3347        "this": True,
3348        "expression": True,
3349        "distinct": False,
3350        "by_name": False,
3351        **QUERY_MODIFIERS,
3352    }
3353
3354    def select(
3355        self: S,
3356        *expressions: t.Optional[ExpOrStr],
3357        append: bool = True,
3358        dialect: DialectType = None,
3359        copy: bool = True,
3360        **opts,
3361    ) -> S:
3362        this = maybe_copy(self, copy)
3363        this.this.unnest().select(*expressions, append=append, dialect=dialect, copy=False, **opts)
3364        this.expression.unnest().select(
3365            *expressions, append=append, dialect=dialect, copy=False, **opts
3366        )
3367        return this
3368
3369    @property
3370    def named_selects(self) -> t.List[str]:
3371        return self.this.unnest().named_selects
3372
3373    @property
3374    def is_star(self) -> bool:
3375        return self.this.is_star or self.expression.is_star
3376
3377    @property
3378    def selects(self) -> t.List[Expression]:
3379        return self.this.unnest().selects
3380
3381    @property
3382    def left(self) -> Query:
3383        return self.this
3384
3385    @property
3386    def right(self) -> Query:
3387        return self.expression
3388
3389
3390class Union(SetOperation):
3391    pass
3392
3393
3394class Except(SetOperation):
3395    pass
3396
3397
3398class Intersect(SetOperation):
3399    pass
3400
3401
3402class Update(DML):
3403    arg_types = {
3404        "with": False,
3405        "this": False,
3406        "expressions": True,
3407        "from": False,
3408        "where": False,
3409        "returning": False,
3410        "order": False,
3411        "limit": False,
3412    }
3413
3414    def table(
3415        self, expression: ExpOrStr, dialect: DialectType = None, copy: bool = True, **opts
3416    ) -> Update:
3417        """
3418        Set the table to update.
3419
3420        Example:
3421            >>> Update().table("my_table").set_("x = 1").sql()
3422            'UPDATE my_table SET x = 1'
3423
3424        Args:
3425            expression : the SQL code strings to parse.
3426                If a `Table` instance is passed, this is used as-is.
3427                If another `Expression` instance is passed, it will be wrapped in a `Table`.
3428            dialect: the dialect used to parse the input expression.
3429            copy: if `False`, modify this expression instance in-place.
3430            opts: other options to use to parse the input expressions.
3431
3432        Returns:
3433            The modified Update expression.
3434        """
3435        return _apply_builder(
3436            expression=expression,
3437            instance=self,
3438            arg="this",
3439            into=Table,
3440            prefix=None,
3441            dialect=dialect,
3442            copy=copy,
3443            **opts,
3444        )
3445
3446    def set_(
3447        self,
3448        *expressions: ExpOrStr,
3449        append: bool = True,
3450        dialect: DialectType = None,
3451        copy: bool = True,
3452        **opts,
3453    ) -> Update:
3454        """
3455        Append to or set the SET expressions.
3456
3457        Example:
3458            >>> Update().table("my_table").set_("x = 1").sql()
3459            'UPDATE my_table SET x = 1'
3460
3461        Args:
3462            *expressions: the SQL code strings to parse.
3463                If `Expression` instance(s) are passed, they will be used as-is.
3464                Multiple expressions are combined with a comma.
3465            append: if `True`, add the new expressions to any existing SET expressions.
3466                Otherwise, this resets the expressions.
3467            dialect: the dialect used to parse the input expressions.
3468            copy: if `False`, modify this expression instance in-place.
3469            opts: other options to use to parse the input expressions.
3470        """
3471        return _apply_list_builder(
3472            *expressions,
3473            instance=self,
3474            arg="expressions",
3475            append=append,
3476            into=Expression,
3477            prefix=None,
3478            dialect=dialect,
3479            copy=copy,
3480            **opts,
3481        )
3482
3483    def where(
3484        self,
3485        *expressions: t.Optional[ExpOrStr],
3486        append: bool = True,
3487        dialect: DialectType = None,
3488        copy: bool = True,
3489        **opts,
3490    ) -> Select:
3491        """
3492        Append to or set the WHERE expressions.
3493
3494        Example:
3495            >>> Update().table("tbl").set_("x = 1").where("x = 'a' OR x < 'b'").sql()
3496            "UPDATE tbl SET x = 1 WHERE x = 'a' OR x < 'b'"
3497
3498        Args:
3499            *expressions: the SQL code strings to parse.
3500                If an `Expression` instance is passed, it will be used as-is.
3501                Multiple expressions are combined with an AND operator.
3502            append: if `True`, AND the new expressions to any existing expression.
3503                Otherwise, this resets the expression.
3504            dialect: the dialect used to parse the input expressions.
3505            copy: if `False`, modify this expression instance in-place.
3506            opts: other options to use to parse the input expressions.
3507
3508        Returns:
3509            Select: the modified expression.
3510        """
3511        return _apply_conjunction_builder(
3512            *expressions,
3513            instance=self,
3514            arg="where",
3515            append=append,
3516            into=Where,
3517            dialect=dialect,
3518            copy=copy,
3519            **opts,
3520        )
3521
3522    def from_(
3523        self,
3524        expression: t.Optional[ExpOrStr] = None,
3525        dialect: DialectType = None,
3526        copy: bool = True,
3527        **opts,
3528    ) -> Update:
3529        """
3530        Set the FROM expression.
3531
3532        Example:
3533            >>> Update().table("my_table").set_("x = 1").from_("baz").sql()
3534            'UPDATE my_table SET x = 1 FROM baz'
3535
3536        Args:
3537            expression : the SQL code strings to parse.
3538                If a `From` instance is passed, this is used as-is.
3539                If another `Expression` instance is passed, it will be wrapped in a `From`.
3540                If nothing is passed in then a from is not applied to the expression
3541            dialect: the dialect used to parse the input expression.
3542            copy: if `False`, modify this expression instance in-place.
3543            opts: other options to use to parse the input expressions.
3544
3545        Returns:
3546            The modified Update expression.
3547        """
3548        if not expression:
3549            return maybe_copy(self, copy)
3550
3551        return _apply_builder(
3552            expression=expression,
3553            instance=self,
3554            arg="from",
3555            into=From,
3556            prefix="FROM",
3557            dialect=dialect,
3558            copy=copy,
3559            **opts,
3560        )
3561
3562    def with_(
3563        self,
3564        alias: ExpOrStr,
3565        as_: ExpOrStr,
3566        recursive: t.Optional[bool] = None,
3567        materialized: t.Optional[bool] = None,
3568        append: bool = True,
3569        dialect: DialectType = None,
3570        copy: bool = True,
3571        **opts,
3572    ) -> Update:
3573        """
3574        Append to or set the common table expressions.
3575
3576        Example:
3577            >>> Update().table("my_table").set_("x = 1").from_("baz").with_("baz", "SELECT id FROM foo").sql()
3578            'WITH baz AS (SELECT id FROM foo) UPDATE my_table SET x = 1 FROM baz'
3579
3580        Args:
3581            alias: the SQL code string to parse as the table name.
3582                If an `Expression` instance is passed, this is used as-is.
3583            as_: the SQL code string to parse as the table expression.
3584                If an `Expression` instance is passed, it will be used as-is.
3585            recursive: set the RECURSIVE part of the expression. Defaults to `False`.
3586            materialized: set the MATERIALIZED part of the expression.
3587            append: if `True`, add to any existing expressions.
3588                Otherwise, this resets the expressions.
3589            dialect: the dialect used to parse the input expression.
3590            copy: if `False`, modify this expression instance in-place.
3591            opts: other options to use to parse the input expressions.
3592
3593        Returns:
3594            The modified expression.
3595        """
3596        return _apply_cte_builder(
3597            self,
3598            alias,
3599            as_,
3600            recursive=recursive,
3601            materialized=materialized,
3602            append=append,
3603            dialect=dialect,
3604            copy=copy,
3605            **opts,
3606        )
3607
3608
3609class Values(UDTF):
3610    arg_types = {"expressions": True, "alias": False}
3611
3612
3613class Var(Expression):
3614    pass
3615
3616
3617class Version(Expression):
3618    """
3619    Time travel, iceberg, bigquery etc
3620    https://trino.io/docs/current/connector/iceberg.html?highlight=snapshot#using-snapshots
3621    https://www.databricks.com/blog/2019/02/04/introducing-delta-time-travel-for-large-scale-data-lakes.html
3622    https://cloud.google.com/bigquery/docs/reference/standard-sql/query-syntax#for_system_time_as_of
3623    https://learn.microsoft.com/en-us/sql/relational-databases/tables/querying-data-in-a-system-versioned-temporal-table?view=sql-server-ver16
3624    this is either TIMESTAMP or VERSION
3625    kind is ("AS OF", "BETWEEN")
3626    """
3627
3628    arg_types = {"this": True, "kind": True, "expression": False}
3629
3630
3631class Schema(Expression):
3632    arg_types = {"this": False, "expressions": False}
3633
3634
3635# https://dev.mysql.com/doc/refman/8.0/en/select.html
3636# https://docs.oracle.com/en/database/oracle/oracle-database/19/sqlrf/SELECT.html
3637class Lock(Expression):
3638    arg_types = {"update": True, "expressions": False, "wait": False}
3639
3640
3641class Select(Query):
3642    arg_types = {
3643        "with": False,
3644        "kind": False,
3645        "expressions": False,
3646        "hint": False,
3647        "distinct": False,
3648        "into": False,
3649        "from": False,
3650        "operation_modifiers": False,
3651        **QUERY_MODIFIERS,
3652    }
3653
3654    def from_(
3655        self, expression: ExpOrStr, dialect: DialectType = None, copy: bool = True, **opts
3656    ) -> Select:
3657        """
3658        Set the FROM expression.
3659
3660        Example:
3661            >>> Select().from_("tbl").select("x").sql()
3662            'SELECT x FROM tbl'
3663
3664        Args:
3665            expression : the SQL code strings to parse.
3666                If a `From` instance is passed, this is used as-is.
3667                If another `Expression` instance is passed, it will be wrapped in a `From`.
3668            dialect: the dialect used to parse the input expression.
3669            copy: if `False`, modify this expression instance in-place.
3670            opts: other options to use to parse the input expressions.
3671
3672        Returns:
3673            The modified Select expression.
3674        """
3675        return _apply_builder(
3676            expression=expression,
3677            instance=self,
3678            arg="from",
3679            into=From,
3680            prefix="FROM",
3681            dialect=dialect,
3682            copy=copy,
3683            **opts,
3684        )
3685
3686    def group_by(
3687        self,
3688        *expressions: t.Optional[ExpOrStr],
3689        append: bool = True,
3690        dialect: DialectType = None,
3691        copy: bool = True,
3692        **opts,
3693    ) -> Select:
3694        """
3695        Set the GROUP BY expression.
3696
3697        Example:
3698            >>> Select().from_("tbl").select("x", "COUNT(1)").group_by("x").sql()
3699            'SELECT x, COUNT(1) FROM tbl GROUP BY x'
3700
3701        Args:
3702            *expressions: the SQL code strings to parse.
3703                If a `Group` instance is passed, this is used as-is.
3704                If another `Expression` instance is passed, it will be wrapped in a `Group`.
3705                If nothing is passed in then a group by is not applied to the expression
3706            append: if `True`, add to any existing expressions.
3707                Otherwise, this flattens all the `Group` expression into a single expression.
3708            dialect: the dialect used to parse the input expression.
3709            copy: if `False`, modify this expression instance in-place.
3710            opts: other options to use to parse the input expressions.
3711
3712        Returns:
3713            The modified Select expression.
3714        """
3715        if not expressions:
3716            return self if not copy else self.copy()
3717
3718        return _apply_child_list_builder(
3719            *expressions,
3720            instance=self,
3721            arg="group",
3722            append=append,
3723            copy=copy,
3724            prefix="GROUP BY",
3725            into=Group,
3726            dialect=dialect,
3727            **opts,
3728        )
3729
3730    def sort_by(
3731        self,
3732        *expressions: t.Optional[ExpOrStr],
3733        append: bool = True,
3734        dialect: DialectType = None,
3735        copy: bool = True,
3736        **opts,
3737    ) -> Select:
3738        """
3739        Set the SORT BY expression.
3740
3741        Example:
3742            >>> Select().from_("tbl").select("x").sort_by("x DESC").sql(dialect="hive")
3743            'SELECT x FROM tbl SORT BY x DESC'
3744
3745        Args:
3746            *expressions: the SQL code strings to parse.
3747                If a `Group` instance is passed, this is used as-is.
3748                If another `Expression` instance is passed, it will be wrapped in a `SORT`.
3749            append: if `True`, add to any existing expressions.
3750                Otherwise, this flattens all the `Order` expression into a single expression.
3751            dialect: the dialect used to parse the input expression.
3752            copy: if `False`, modify this expression instance in-place.
3753            opts: other options to use to parse the input expressions.
3754
3755        Returns:
3756            The modified Select expression.
3757        """
3758        return _apply_child_list_builder(
3759            *expressions,
3760            instance=self,
3761            arg="sort",
3762            append=append,
3763            copy=copy,
3764            prefix="SORT BY",
3765            into=Sort,
3766            dialect=dialect,
3767            **opts,
3768        )
3769
3770    def cluster_by(
3771        self,
3772        *expressions: t.Optional[ExpOrStr],
3773        append: bool = True,
3774        dialect: DialectType = None,
3775        copy: bool = True,
3776        **opts,
3777    ) -> Select:
3778        """
3779        Set the CLUSTER BY expression.
3780
3781        Example:
3782            >>> Select().from_("tbl").select("x").cluster_by("x DESC").sql(dialect="hive")
3783            'SELECT x FROM tbl CLUSTER BY x DESC'
3784
3785        Args:
3786            *expressions: the SQL code strings to parse.
3787                If a `Group` instance is passed, this is used as-is.
3788                If another `Expression` instance is passed, it will be wrapped in a `Cluster`.
3789            append: if `True`, add to any existing expressions.
3790                Otherwise, this flattens all the `Order` expression into a single expression.
3791            dialect: the dialect used to parse the input expression.
3792            copy: if `False`, modify this expression instance in-place.
3793            opts: other options to use to parse the input expressions.
3794
3795        Returns:
3796            The modified Select expression.
3797        """
3798        return _apply_child_list_builder(
3799            *expressions,
3800            instance=self,
3801            arg="cluster",
3802            append=append,
3803            copy=copy,
3804            prefix="CLUSTER BY",
3805            into=Cluster,
3806            dialect=dialect,
3807            **opts,
3808        )
3809
3810    def select(
3811        self,
3812        *expressions: t.Optional[ExpOrStr],
3813        append: bool = True,
3814        dialect: DialectType = None,
3815        copy: bool = True,
3816        **opts,
3817    ) -> Select:
3818        return _apply_list_builder(
3819            *expressions,
3820            instance=self,
3821            arg="expressions",
3822            append=append,
3823            dialect=dialect,
3824            into=Expression,
3825            copy=copy,
3826            **opts,
3827        )
3828
3829    def lateral(
3830        self,
3831        *expressions: t.Optional[ExpOrStr],
3832        append: bool = True,
3833        dialect: DialectType = None,
3834        copy: bool = True,
3835        **opts,
3836    ) -> Select:
3837        """
3838        Append to or set the LATERAL expressions.
3839
3840        Example:
3841            >>> Select().select("x").lateral("OUTER explode(y) tbl2 AS z").from_("tbl").sql()
3842            'SELECT x FROM tbl LATERAL VIEW OUTER EXPLODE(y) tbl2 AS z'
3843
3844        Args:
3845            *expressions: the SQL code strings to parse.
3846                If an `Expression` instance is passed, it will be used as-is.
3847            append: if `True`, add to any existing expressions.
3848                Otherwise, this resets the expressions.
3849            dialect: the dialect used to parse the input expressions.
3850            copy: if `False`, modify this expression instance in-place.
3851            opts: other options to use to parse the input expressions.
3852
3853        Returns:
3854            The modified Select expression.
3855        """
3856        return _apply_list_builder(
3857            *expressions,
3858            instance=self,
3859            arg="laterals",
3860            append=append,
3861            into=Lateral,
3862            prefix="LATERAL VIEW",
3863            dialect=dialect,
3864            copy=copy,
3865            **opts,
3866        )
3867
3868    def join(
3869        self,
3870        expression: ExpOrStr,
3871        on: t.Optional[ExpOrStr] = None,
3872        using: t.Optional[ExpOrStr | t.Collection[ExpOrStr]] = None,
3873        append: bool = True,
3874        join_type: t.Optional[str] = None,
3875        join_alias: t.Optional[Identifier | str] = None,
3876        dialect: DialectType = None,
3877        copy: bool = True,
3878        **opts,
3879    ) -> Select:
3880        """
3881        Append to or set the JOIN expressions.
3882
3883        Example:
3884            >>> Select().select("*").from_("tbl").join("tbl2", on="tbl1.y = tbl2.y").sql()
3885            'SELECT * FROM tbl JOIN tbl2 ON tbl1.y = tbl2.y'
3886
3887            >>> Select().select("1").from_("a").join("b", using=["x", "y", "z"]).sql()
3888            'SELECT 1 FROM a JOIN b USING (x, y, z)'
3889
3890            Use `join_type` to change the type of join:
3891
3892            >>> Select().select("*").from_("tbl").join("tbl2", on="tbl1.y = tbl2.y", join_type="left outer").sql()
3893            'SELECT * FROM tbl LEFT OUTER JOIN tbl2 ON tbl1.y = tbl2.y'
3894
3895        Args:
3896            expression: the SQL code string to parse.
3897                If an `Expression` instance is passed, it will be used as-is.
3898            on: optionally specify the join "on" criteria as a SQL string.
3899                If an `Expression` instance is passed, it will be used as-is.
3900            using: optionally specify the join "using" criteria as a SQL string.
3901                If an `Expression` instance is passed, it will be used as-is.
3902            append: if `True`, add to any existing expressions.
3903                Otherwise, this resets the expressions.
3904            join_type: if set, alter the parsed join type.
3905            join_alias: an optional alias for the joined source.
3906            dialect: the dialect used to parse the input expressions.
3907            copy: if `False`, modify this expression instance in-place.
3908            opts: other options to use to parse the input expressions.
3909
3910        Returns:
3911            Select: the modified expression.
3912        """
3913        parse_args: t.Dict[str, t.Any] = {"dialect": dialect, **opts}
3914
3915        try:
3916            expression = maybe_parse(expression, into=Join, prefix="JOIN", **parse_args)
3917        except ParseError:
3918            expression = maybe_parse(expression, into=(Join, Expression), **parse_args)
3919
3920        join = expression if isinstance(expression, Join) else Join(this=expression)
3921
3922        if isinstance(join.this, Select):
3923            join.this.replace(join.this.subquery())
3924
3925        if join_type:
3926            method: t.Optional[Token]
3927            side: t.Optional[Token]
3928            kind: t.Optional[Token]
3929
3930            method, side, kind = maybe_parse(join_type, into="JOIN_TYPE", **parse_args)  # type: ignore
3931
3932            if method:
3933                join.set("method", method.text)
3934            if side:
3935                join.set("side", side.text)
3936            if kind:
3937                join.set("kind", kind.text)
3938
3939        if on:
3940            on = and_(*ensure_list(on), dialect=dialect, copy=copy, **opts)
3941            join.set("on", on)
3942
3943        if using:
3944            join = _apply_list_builder(
3945                *ensure_list(using),
3946                instance=join,
3947                arg="using",
3948                append=append,
3949                copy=copy,
3950                into=Identifier,
3951                **opts,
3952            )
3953
3954        if join_alias:
3955            join.set("this", alias_(join.this, join_alias, table=True))
3956
3957        return _apply_list_builder(
3958            join,
3959            instance=self,
3960            arg="joins",
3961            append=append,
3962            copy=copy,
3963            **opts,
3964        )
3965
3966    def where(
3967        self,
3968        *expressions: t.Optional[ExpOrStr],
3969        append: bool = True,
3970        dialect: DialectType = None,
3971        copy: bool = True,
3972        **opts,
3973    ) -> Select:
3974        """
3975        Append to or set the WHERE expressions.
3976
3977        Example:
3978            >>> Select().select("x").from_("tbl").where("x = 'a' OR x < 'b'").sql()
3979            "SELECT x FROM tbl WHERE x = 'a' OR x < 'b'"
3980
3981        Args:
3982            *expressions: the SQL code strings to parse.
3983                If an `Expression` instance is passed, it will be used as-is.
3984                Multiple expressions are combined with an AND operator.
3985            append: if `True`, AND the new expressions to any existing expression.
3986                Otherwise, this resets the expression.
3987            dialect: the dialect used to parse the input expressions.
3988            copy: if `False`, modify this expression instance in-place.
3989            opts: other options to use to parse the input expressions.
3990
3991        Returns:
3992            Select: the modified expression.
3993        """
3994        return _apply_conjunction_builder(
3995            *expressions,
3996            instance=self,
3997            arg="where",
3998            append=append,
3999            into=Where,
4000            dialect=dialect,
4001            copy=copy,
4002            **opts,
4003        )
4004
4005    def having(
4006        self,
4007        *expressions: t.Optional[ExpOrStr],
4008        append: bool = True,
4009        dialect: DialectType = None,
4010        copy: bool = True,
4011        **opts,
4012    ) -> Select:
4013        """
4014        Append to or set the HAVING expressions.
4015
4016        Example:
4017            >>> Select().select("x", "COUNT(y)").from_("tbl").group_by("x").having("COUNT(y) > 3").sql()
4018            'SELECT x, COUNT(y) FROM tbl GROUP BY x HAVING COUNT(y) > 3'
4019
4020        Args:
4021            *expressions: the SQL code strings to parse.
4022                If an `Expression` instance is passed, it will be used as-is.
4023                Multiple expressions are combined with an AND operator.
4024            append: if `True`, AND the new expressions to any existing expression.
4025                Otherwise, this resets the expression.
4026            dialect: the dialect used to parse the input expressions.
4027            copy: if `False`, modify this expression instance in-place.
4028            opts: other options to use to parse the input expressions.
4029
4030        Returns:
4031            The modified Select expression.
4032        """
4033        return _apply_conjunction_builder(
4034            *expressions,
4035            instance=self,
4036            arg="having",
4037            append=append,
4038            into=Having,
4039            dialect=dialect,
4040            copy=copy,
4041            **opts,
4042        )
4043
4044    def window(
4045        self,
4046        *expressions: t.Optional[ExpOrStr],
4047        append: bool = True,
4048        dialect: DialectType = None,
4049        copy: bool = True,
4050        **opts,
4051    ) -> Select:
4052        return _apply_list_builder(
4053            *expressions,
4054            instance=self,
4055            arg="windows",
4056            append=append,
4057            into=Window,
4058            dialect=dialect,
4059            copy=copy,
4060            **opts,
4061        )
4062
4063    def qualify(
4064        self,
4065        *expressions: t.Optional[ExpOrStr],
4066        append: bool = True,
4067        dialect: DialectType = None,
4068        copy: bool = True,
4069        **opts,
4070    ) -> Select:
4071        return _apply_conjunction_builder(
4072            *expressions,
4073            instance=self,
4074            arg="qualify",
4075            append=append,
4076            into=Qualify,
4077            dialect=dialect,
4078            copy=copy,
4079            **opts,
4080        )
4081
4082    def distinct(
4083        self, *ons: t.Optional[ExpOrStr], distinct: bool = True, copy: bool = True
4084    ) -> Select:
4085        """
4086        Set the OFFSET expression.
4087
4088        Example:
4089            >>> Select().from_("tbl").select("x").distinct().sql()
4090            'SELECT DISTINCT x FROM tbl'
4091
4092        Args:
4093            ons: the expressions to distinct on
4094            distinct: whether the Select should be distinct
4095            copy: if `False`, modify this expression instance in-place.
4096
4097        Returns:
4098            Select: the modified expression.
4099        """
4100        instance = maybe_copy(self, copy)
4101        on = Tuple(expressions=[maybe_parse(on, copy=copy) for on in ons if on]) if ons else None
4102        instance.set("distinct", Distinct(on=on) if distinct else None)
4103        return instance
4104
4105    def ctas(
4106        self,
4107        table: ExpOrStr,
4108        properties: t.Optional[t.Dict] = None,
4109        dialect: DialectType = None,
4110        copy: bool = True,
4111        **opts,
4112    ) -> Create:
4113        """
4114        Convert this expression to a CREATE TABLE AS statement.
4115
4116        Example:
4117            >>> Select().select("*").from_("tbl").ctas("x").sql()
4118            'CREATE TABLE x AS SELECT * FROM tbl'
4119
4120        Args:
4121            table: the SQL code string to parse as the table name.
4122                If another `Expression` instance is passed, it will be used as-is.
4123            properties: an optional mapping of table properties
4124            dialect: the dialect used to parse the input table.
4125            copy: if `False`, modify this expression instance in-place.
4126            opts: other options to use to parse the input table.
4127
4128        Returns:
4129            The new Create expression.
4130        """
4131        instance = maybe_copy(self, copy)
4132        table_expression = maybe_parse(table, into=Table, dialect=dialect, **opts)
4133
4134        properties_expression = None
4135        if properties:
4136            properties_expression = Properties.from_dict(properties)
4137
4138        return Create(
4139            this=table_expression,
4140            kind="TABLE",
4141            expression=instance,
4142            properties=properties_expression,
4143        )
4144
4145    def lock(self, update: bool = True, copy: bool = True) -> Select:
4146        """
4147        Set the locking read mode for this expression.
4148
4149        Examples:
4150            >>> Select().select("x").from_("tbl").where("x = 'a'").lock().sql("mysql")
4151            "SELECT x FROM tbl WHERE x = 'a' FOR UPDATE"
4152
4153            >>> Select().select("x").from_("tbl").where("x = 'a'").lock(update=False).sql("mysql")
4154            "SELECT x FROM tbl WHERE x = 'a' FOR SHARE"
4155
4156        Args:
4157            update: if `True`, the locking type will be `FOR UPDATE`, else it will be `FOR SHARE`.
4158            copy: if `False`, modify this expression instance in-place.
4159
4160        Returns:
4161            The modified expression.
4162        """
4163        inst = maybe_copy(self, copy)
4164        inst.set("locks", [Lock(update=update)])
4165
4166        return inst
4167
4168    def hint(self, *hints: ExpOrStr, dialect: DialectType = None, copy: bool = True) -> Select:
4169        """
4170        Set hints for this expression.
4171
4172        Examples:
4173            >>> Select().select("x").from_("tbl").hint("BROADCAST(y)").sql(dialect="spark")
4174            'SELECT /*+ BROADCAST(y) */ x FROM tbl'
4175
4176        Args:
4177            hints: The SQL code strings to parse as the hints.
4178                If an `Expression` instance is passed, it will be used as-is.
4179            dialect: The dialect used to parse the hints.
4180            copy: If `False`, modify this expression instance in-place.
4181
4182        Returns:
4183            The modified expression.
4184        """
4185        inst = maybe_copy(self, copy)
4186        inst.set(
4187            "hint", Hint(expressions=[maybe_parse(h, copy=copy, dialect=dialect) for h in hints])
4188        )
4189
4190        return inst
4191
4192    @property
4193    def named_selects(self) -> t.List[str]:
4194        return [e.output_name for e in self.expressions if e.alias_or_name]
4195
4196    @property
4197    def is_star(self) -> bool:
4198        return any(expression.is_star for expression in self.expressions)
4199
4200    @property
4201    def selects(self) -> t.List[Expression]:
4202        return self.expressions
4203
4204
4205UNWRAPPED_QUERIES = (Select, SetOperation)
4206
4207
4208class Subquery(DerivedTable, Query):
4209    arg_types = {
4210        "this": True,
4211        "alias": False,
4212        "with": False,
4213        **QUERY_MODIFIERS,
4214    }
4215
4216    def unnest(self):
4217        """Returns the first non subquery."""
4218        expression = self
4219        while isinstance(expression, Subquery):
4220            expression = expression.this
4221        return expression
4222
4223    def unwrap(self) -> Subquery:
4224        expression = self
4225        while expression.same_parent and expression.is_wrapper:
4226            expression = t.cast(Subquery, expression.parent)
4227        return expression
4228
4229    def select(
4230        self,
4231        *expressions: t.Optional[ExpOrStr],
4232        append: bool = True,
4233        dialect: DialectType = None,
4234        copy: bool = True,
4235        **opts,
4236    ) -> Subquery:
4237        this = maybe_copy(self, copy)
4238        this.unnest().select(*expressions, append=append, dialect=dialect, copy=False, **opts)
4239        return this
4240
4241    @property
4242    def is_wrapper(self) -> bool:
4243        """
4244        Whether this Subquery acts as a simple wrapper around another expression.
4245
4246        SELECT * FROM (((SELECT * FROM t)))
4247                      ^
4248                      This corresponds to a "wrapper" Subquery node
4249        """
4250        return all(v is None for k, v in self.args.items() if k != "this")
4251
4252    @property
4253    def is_star(self) -> bool:
4254        return self.this.is_star
4255
4256    @property
4257    def output_name(self) -> str:
4258        return self.alias
4259
4260
4261class TableSample(Expression):
4262    arg_types = {
4263        "expressions": False,
4264        "method": False,
4265        "bucket_numerator": False,
4266        "bucket_denominator": False,
4267        "bucket_field": False,
4268        "percent": False,
4269        "rows": False,
4270        "size": False,
4271        "seed": False,
4272    }
4273
4274
4275class Tag(Expression):
4276    """Tags are used for generating arbitrary sql like SELECT <span>x</span>."""
4277
4278    arg_types = {
4279        "this": False,
4280        "prefix": False,
4281        "postfix": False,
4282    }
4283
4284
4285# Represents both the standard SQL PIVOT operator and DuckDB's "simplified" PIVOT syntax
4286# https://duckdb.org/docs/sql/statements/pivot
4287class Pivot(Expression):
4288    arg_types = {
4289        "this": False,
4290        "alias": False,
4291        "expressions": False,
4292        "field": False,
4293        "unpivot": False,
4294        "using": False,
4295        "group": False,
4296        "columns": False,
4297        "include_nulls": False,
4298        "default_on_null": False,
4299        "into": False,
4300    }
4301
4302    @property
4303    def unpivot(self) -> bool:
4304        return bool(self.args.get("unpivot"))
4305
4306
4307# https://duckdb.org/docs/sql/statements/unpivot#simplified-unpivot-syntax
4308# UNPIVOT ... INTO [NAME <col_name> VALUE <col_value>][...,]
4309class UnpivotColumns(Expression):
4310    arg_types = {"this": True, "expressions": True}
4311
4312
4313class Window(Condition):
4314    arg_types = {
4315        "this": True,
4316        "partition_by": False,
4317        "order": False,
4318        "spec": False,
4319        "alias": False,
4320        "over": False,
4321        "first": False,
4322    }
4323
4324
4325class WindowSpec(Expression):
4326    arg_types = {
4327        "kind": False,
4328        "start": False,
4329        "start_side": False,
4330        "end": False,
4331        "end_side": False,
4332    }
4333
4334
4335class PreWhere(Expression):
4336    pass
4337
4338
4339class Where(Expression):
4340    pass
4341
4342
4343class Star(Expression):
4344    arg_types = {"except": False, "replace": False, "rename": False}
4345
4346    @property
4347    def name(self) -> str:
4348        return "*"
4349
4350    @property
4351    def output_name(self) -> str:
4352        return self.name
4353
4354
4355class Parameter(Condition):
4356    arg_types = {"this": True, "expression": False}
4357
4358
4359class SessionParameter(Condition):
4360    arg_types = {"this": True, "kind": False}
4361
4362
4363class Placeholder(Condition):
4364    arg_types = {"this": False, "kind": False}
4365
4366    @property
4367    def name(self) -> str:
4368        return self.this or "?"
4369
4370
4371class Null(Condition):
4372    arg_types: t.Dict[str, t.Any] = {}
4373
4374    @property
4375    def name(self) -> str:
4376        return "NULL"
4377
4378    def to_py(self) -> Lit[None]:
4379        return None
4380
4381
4382class Boolean(Condition):
4383    def to_py(self) -> bool:
4384        return self.this
4385
4386
4387class DataTypeParam(Expression):
4388    arg_types = {"this": True, "expression": False}
4389
4390    @property
4391    def name(self) -> str:
4392        return self.this.name
4393
4394
4395# The `nullable` arg is helpful when transpiling types from other dialects to ClickHouse, which
4396# assumes non-nullable types by default. Values `None` and `True` mean the type is nullable.
4397class DataType(Expression):
4398    arg_types = {
4399        "this": True,
4400        "expressions": False,
4401        "nested": False,
4402        "values": False,
4403        "prefix": False,
4404        "kind": False,
4405        "nullable": False,
4406    }
4407
4408    class Type(AutoName):
4409        ARRAY = auto()
4410        AGGREGATEFUNCTION = auto()
4411        SIMPLEAGGREGATEFUNCTION = auto()
4412        BIGDECIMAL = auto()
4413        BIGINT = auto()
4414        BIGSERIAL = auto()
4415        BINARY = auto()
4416        BIT = auto()
4417        BLOB = auto()
4418        BOOLEAN = auto()
4419        BPCHAR = auto()
4420        CHAR = auto()
4421        DATE = auto()
4422        DATE32 = auto()
4423        DATEMULTIRANGE = auto()
4424        DATERANGE = auto()
4425        DATETIME = auto()
4426        DATETIME2 = auto()
4427        DATETIME64 = auto()
4428        DECIMAL = auto()
4429        DECIMAL32 = auto()
4430        DECIMAL64 = auto()
4431        DECIMAL128 = auto()
4432        DECIMAL256 = auto()
4433        DOUBLE = auto()
4434        DYNAMIC = auto()
4435        ENUM = auto()
4436        ENUM8 = auto()
4437        ENUM16 = auto()
4438        FIXEDSTRING = auto()
4439        FLOAT = auto()
4440        GEOGRAPHY = auto()
4441        GEOMETRY = auto()
4442        POINT = auto()
4443        RING = auto()
4444        LINESTRING = auto()
4445        MULTILINESTRING = auto()
4446        POLYGON = auto()
4447        MULTIPOLYGON = auto()
4448        HLLSKETCH = auto()
4449        HSTORE = auto()
4450        IMAGE = auto()
4451        INET = auto()
4452        INT = auto()
4453        INT128 = auto()
4454        INT256 = auto()
4455        INT4MULTIRANGE = auto()
4456        INT4RANGE = auto()
4457        INT8MULTIRANGE = auto()
4458        INT8RANGE = auto()
4459        INTERVAL = auto()
4460        IPADDRESS = auto()
4461        IPPREFIX = auto()
4462        IPV4 = auto()
4463        IPV6 = auto()
4464        JSON = auto()
4465        JSONB = auto()
4466        LIST = auto()
4467        LONGBLOB = auto()
4468        LONGTEXT = auto()
4469        LOWCARDINALITY = auto()
4470        MAP = auto()
4471        MEDIUMBLOB = auto()
4472        MEDIUMINT = auto()
4473        MEDIUMTEXT = auto()
4474        MONEY = auto()
4475        NAME = auto()
4476        NCHAR = auto()
4477        NESTED = auto()
4478        NULL = auto()
4479        NUMMULTIRANGE = auto()
4480        NUMRANGE = auto()
4481        NVARCHAR = auto()
4482        OBJECT = auto()
4483        RANGE = auto()
4484        ROWVERSION = auto()
4485        SERIAL = auto()
4486        SET = auto()
4487        SMALLDATETIME = auto()
4488        SMALLINT = auto()
4489        SMALLMONEY = auto()
4490        SMALLSERIAL = auto()
4491        STRUCT = auto()
4492        SUPER = auto()
4493        TEXT = auto()
4494        TINYBLOB = auto()
4495        TINYTEXT = auto()
4496        TIME = auto()
4497        TIMETZ = auto()
4498        TIMESTAMP = auto()
4499        TIMESTAMPNTZ = auto()
4500        TIMESTAMPLTZ = auto()
4501        TIMESTAMPTZ = auto()
4502        TIMESTAMP_S = auto()
4503        TIMESTAMP_MS = auto()
4504        TIMESTAMP_NS = auto()
4505        TINYINT = auto()
4506        TSMULTIRANGE = auto()
4507        TSRANGE = auto()
4508        TSTZMULTIRANGE = auto()
4509        TSTZRANGE = auto()
4510        UBIGINT = auto()
4511        UINT = auto()
4512        UINT128 = auto()
4513        UINT256 = auto()
4514        UMEDIUMINT = auto()
4515        UDECIMAL = auto()
4516        UDOUBLE = auto()
4517        UNION = auto()
4518        UNKNOWN = auto()  # Sentinel value, useful for type annotation
4519        USERDEFINED = "USER-DEFINED"
4520        USMALLINT = auto()
4521        UTINYINT = auto()
4522        UUID = auto()
4523        VARBINARY = auto()
4524        VARCHAR = auto()
4525        VARIANT = auto()
4526        VECTOR = auto()
4527        XML = auto()
4528        YEAR = auto()
4529        TDIGEST = auto()
4530
4531    STRUCT_TYPES = {
4532        Type.NESTED,
4533        Type.OBJECT,
4534        Type.STRUCT,
4535        Type.UNION,
4536    }
4537
4538    ARRAY_TYPES = {
4539        Type.ARRAY,
4540        Type.LIST,
4541    }
4542
4543    NESTED_TYPES = {
4544        *STRUCT_TYPES,
4545        *ARRAY_TYPES,
4546        Type.MAP,
4547    }
4548
4549    TEXT_TYPES = {
4550        Type.CHAR,
4551        Type.NCHAR,
4552        Type.NVARCHAR,
4553        Type.TEXT,
4554        Type.VARCHAR,
4555        Type.NAME,
4556    }
4557
4558    SIGNED_INTEGER_TYPES = {
4559        Type.BIGINT,
4560        Type.INT,
4561        Type.INT128,
4562        Type.INT256,
4563        Type.MEDIUMINT,
4564        Type.SMALLINT,
4565        Type.TINYINT,
4566    }
4567
4568    UNSIGNED_INTEGER_TYPES = {
4569        Type.UBIGINT,
4570        Type.UINT,
4571        Type.UINT128,
4572        Type.UINT256,
4573        Type.UMEDIUMINT,
4574        Type.USMALLINT,
4575        Type.UTINYINT,
4576    }
4577
4578    INTEGER_TYPES = {
4579        *SIGNED_INTEGER_TYPES,
4580        *UNSIGNED_INTEGER_TYPES,
4581        Type.BIT,
4582    }
4583
4584    FLOAT_TYPES = {
4585        Type.DOUBLE,
4586        Type.FLOAT,
4587    }
4588
4589    REAL_TYPES = {
4590        *FLOAT_TYPES,
4591        Type.BIGDECIMAL,
4592        Type.DECIMAL,
4593        Type.DECIMAL32,
4594        Type.DECIMAL64,
4595        Type.DECIMAL128,
4596        Type.DECIMAL256,
4597        Type.MONEY,
4598        Type.SMALLMONEY,
4599        Type.UDECIMAL,
4600        Type.UDOUBLE,
4601    }
4602
4603    NUMERIC_TYPES = {
4604        *INTEGER_TYPES,
4605        *REAL_TYPES,
4606    }
4607
4608    TEMPORAL_TYPES = {
4609        Type.DATE,
4610        Type.DATE32,
4611        Type.DATETIME,
4612        Type.DATETIME2,
4613        Type.DATETIME64,
4614        Type.SMALLDATETIME,
4615        Type.TIME,
4616        Type.TIMESTAMP,
4617        Type.TIMESTAMPNTZ,
4618        Type.TIMESTAMPLTZ,
4619        Type.TIMESTAMPTZ,
4620        Type.TIMESTAMP_MS,
4621        Type.TIMESTAMP_NS,
4622        Type.TIMESTAMP_S,
4623        Type.TIMETZ,
4624    }
4625
4626    @classmethod
4627    def build(
4628        cls,
4629        dtype: DATA_TYPE,
4630        dialect: DialectType = None,
4631        udt: bool = False,
4632        copy: bool = True,
4633        **kwargs,
4634    ) -> DataType:
4635        """
4636        Constructs a DataType object.
4637
4638        Args:
4639            dtype: the data type of interest.
4640            dialect: the dialect to use for parsing `dtype`, in case it's a string.
4641            udt: when set to True, `dtype` will be used as-is if it can't be parsed into a
4642                DataType, thus creating a user-defined type.
4643            copy: whether to copy the data type.
4644            kwargs: additional arguments to pass in the constructor of DataType.
4645
4646        Returns:
4647            The constructed DataType object.
4648        """
4649        from sqlglot import parse_one
4650
4651        if isinstance(dtype, str):
4652            if dtype.upper() == "UNKNOWN":
4653                return DataType(this=DataType.Type.UNKNOWN, **kwargs)
4654
4655            try:
4656                data_type_exp = parse_one(
4657                    dtype, read=dialect, into=DataType, error_level=ErrorLevel.IGNORE
4658                )
4659            except ParseError:
4660                if udt:
4661                    return DataType(this=DataType.Type.USERDEFINED, kind=dtype, **kwargs)
4662                raise
4663        elif isinstance(dtype, DataType.Type):
4664            data_type_exp = DataType(this=dtype)
4665        elif isinstance(dtype, DataType):
4666            return maybe_copy(dtype, copy)
4667        else:
4668            raise ValueError(f"Invalid data type: {type(dtype)}. Expected str or DataType.Type")
4669
4670        return DataType(**{**data_type_exp.args, **kwargs})
4671
4672    def is_type(self, *dtypes: DATA_TYPE, check_nullable: bool = False) -> bool:
4673        """
4674        Checks whether this DataType matches one of the provided data types. Nested types or precision
4675        will be compared using "structural equivalence" semantics, so e.g. array<int> != array<float>.
4676
4677        Args:
4678            dtypes: the data types to compare this DataType to.
4679            check_nullable: whether to take the NULLABLE type constructor into account for the comparison.
4680                If false, it means that NULLABLE<INT> is equivalent to INT.
4681
4682        Returns:
4683            True, if and only if there is a type in `dtypes` which is equal to this DataType.
4684        """
4685        self_is_nullable = self.args.get("nullable")
4686        for dtype in dtypes:
4687            other_type = DataType.build(dtype, copy=False, udt=True)
4688            other_is_nullable = other_type.args.get("nullable")
4689            if (
4690                other_type.expressions
4691                or (check_nullable and (self_is_nullable or other_is_nullable))
4692                or self.this == DataType.Type.USERDEFINED
4693                or other_type.this == DataType.Type.USERDEFINED
4694            ):
4695                matches = self == other_type
4696            else:
4697                matches = self.this == other_type.this
4698
4699            if matches:
4700                return True
4701        return False
4702
4703
4704DATA_TYPE = t.Union[str, DataType, DataType.Type]
4705
4706
4707# https://www.postgresql.org/docs/15/datatype-pseudo.html
4708class PseudoType(DataType):
4709    arg_types = {"this": True}
4710
4711
4712# https://www.postgresql.org/docs/15/datatype-oid.html
4713class ObjectIdentifier(DataType):
4714    arg_types = {"this": True}
4715
4716
4717# WHERE x <OP> EXISTS|ALL|ANY|SOME(SELECT ...)
4718class SubqueryPredicate(Predicate):
4719    pass
4720
4721
4722class All(SubqueryPredicate):
4723    pass
4724
4725
4726class Any(SubqueryPredicate):
4727    pass
4728
4729
4730# Commands to interact with the databases or engines. For most of the command
4731# expressions we parse whatever comes after the command's name as a string.
4732class Command(Expression):
4733    arg_types = {"this": True, "expression": False}
4734
4735
4736class Transaction(Expression):
4737    arg_types = {"this": False, "modes": False, "mark": False}
4738
4739
4740class Commit(Expression):
4741    arg_types = {"chain": False, "this": False, "durability": False}
4742
4743
4744class Rollback(Expression):
4745    arg_types = {"savepoint": False, "this": False}
4746
4747
4748class Alter(Expression):
4749    arg_types = {
4750        "this": True,
4751        "kind": True,
4752        "actions": True,
4753        "exists": False,
4754        "only": False,
4755        "options": False,
4756        "cluster": False,
4757        "not_valid": False,
4758    }
4759
4760    @property
4761    def kind(self) -> t.Optional[str]:
4762        kind = self.args.get("kind")
4763        return kind and kind.upper()
4764
4765    @property
4766    def actions(self) -> t.List[Expression]:
4767        return self.args.get("actions") or []
4768
4769
4770class Analyze(Expression):
4771    arg_types = {
4772        "kind": False,
4773        "this": False,
4774        "options": False,
4775        "mode": False,
4776        "partition": False,
4777        "expression": False,
4778        "properties": False,
4779    }
4780
4781
4782class AnalyzeStatistics(Expression):
4783    arg_types = {
4784        "kind": True,
4785        "option": False,
4786        "this": False,
4787        "expressions": False,
4788    }
4789
4790
4791class AnalyzeHistogram(Expression):
4792    arg_types = {
4793        "this": True,
4794        "expressions": True,
4795        "expression": False,
4796        "update_options": False,
4797    }
4798
4799
4800class AnalyzeSample(Expression):
4801    arg_types = {"kind": True, "sample": True}
4802
4803
4804class AnalyzeListChainedRows(Expression):
4805    arg_types = {"expression": False}
4806
4807
4808class AnalyzeDelete(Expression):
4809    arg_types = {"kind": False}
4810
4811
4812class AnalyzeWith(Expression):
4813    arg_types = {"expressions": True}
4814
4815
4816class AnalyzeValidate(Expression):
4817    arg_types = {
4818        "kind": True,
4819        "this": False,
4820        "expression": False,
4821    }
4822
4823
4824class AnalyzeColumns(Expression):
4825    pass
4826
4827
4828class UsingData(Expression):
4829    pass
4830
4831
4832class AddConstraint(Expression):
4833    arg_types = {"expressions": True}
4834
4835
4836class AttachOption(Expression):
4837    arg_types = {"this": True, "expression": False}
4838
4839
4840class DropPartition(Expression):
4841    arg_types = {"expressions": True, "exists": False}
4842
4843
4844# https://clickhouse.com/docs/en/sql-reference/statements/alter/partition#replace-partition
4845class ReplacePartition(Expression):
4846    arg_types = {"expression": True, "source": True}
4847
4848
4849# Binary expressions like (ADD a b)
4850class Binary(Condition):
4851    arg_types = {"this": True, "expression": True}
4852
4853    @property
4854    def left(self) -> Expression:
4855        return self.this
4856
4857    @property
4858    def right(self) -> Expression:
4859        return self.expression
4860
4861
4862class Add(Binary):
4863    pass
4864
4865
4866class Connector(Binary):
4867    pass
4868
4869
4870class BitwiseAnd(Binary):
4871    pass
4872
4873
4874class BitwiseLeftShift(Binary):
4875    pass
4876
4877
4878class BitwiseOr(Binary):
4879    pass
4880
4881
4882class BitwiseRightShift(Binary):
4883    pass
4884
4885
4886class BitwiseXor(Binary):
4887    pass
4888
4889
4890class Div(Binary):
4891    arg_types = {"this": True, "expression": True, "typed": False, "safe": False}
4892
4893
4894class Overlaps(Binary):
4895    pass
4896
4897
4898class Dot(Binary):
4899    @property
4900    def is_star(self) -> bool:
4901        return self.expression.is_star
4902
4903    @property
4904    def name(self) -> str:
4905        return self.expression.name
4906
4907    @property
4908    def output_name(self) -> str:
4909        return self.name
4910
4911    @classmethod
4912    def build(self, expressions: t.Sequence[Expression]) -> Dot:
4913        """Build a Dot object with a sequence of expressions."""
4914        if len(expressions) < 2:
4915            raise ValueError("Dot requires >= 2 expressions.")
4916
4917        return t.cast(Dot, reduce(lambda x, y: Dot(this=x, expression=y), expressions))
4918
4919    @property
4920    def parts(self) -> t.List[Expression]:
4921        """Return the parts of a table / column in order catalog, db, table."""
4922        this, *parts = self.flatten()
4923
4924        parts.reverse()
4925
4926        for arg in COLUMN_PARTS:
4927            part = this.args.get(arg)
4928
4929            if isinstance(part, Expression):
4930                parts.append(part)
4931
4932        parts.reverse()
4933        return parts
4934
4935
4936class DPipe(Binary):
4937    arg_types = {"this": True, "expression": True, "safe": False}
4938
4939
4940class EQ(Binary, Predicate):
4941    pass
4942
4943
4944class NullSafeEQ(Binary, Predicate):
4945    pass
4946
4947
4948class NullSafeNEQ(Binary, Predicate):
4949    pass
4950
4951
4952# Represents e.g. := in DuckDB which is mostly used for setting parameters
4953class PropertyEQ(Binary):
4954    pass
4955
4956
4957class Distance(Binary):
4958    pass
4959
4960
4961class Escape(Binary):
4962    pass
4963
4964
4965class Glob(Binary, Predicate):
4966    pass
4967
4968
4969class GT(Binary, Predicate):
4970    pass
4971
4972
4973class GTE(Binary, Predicate):
4974    pass
4975
4976
4977class ILike(Binary, Predicate):
4978    pass
4979
4980
4981class ILikeAny(Binary, Predicate):
4982    pass
4983
4984
4985class IntDiv(Binary):
4986    pass
4987
4988
4989class Is(Binary, Predicate):
4990    pass
4991
4992
4993class Kwarg(Binary):
4994    """Kwarg in special functions like func(kwarg => y)."""
4995
4996
4997class Like(Binary, Predicate):
4998    pass
4999
5000
5001class LikeAny(Binary, Predicate):
5002    pass
5003
5004
5005class LT(Binary, Predicate):
5006    pass
5007
5008
5009class LTE(Binary, Predicate):
5010    pass
5011
5012
5013class Mod(Binary):
5014    pass
5015
5016
5017class Mul(Binary):
5018    pass
5019
5020
5021class NEQ(Binary, Predicate):
5022    pass
5023
5024
5025# https://www.postgresql.org/docs/current/ddl-schemas.html#DDL-SCHEMAS-PATH
5026class Operator(Binary):
5027    arg_types = {"this": True, "operator": True, "expression": True}
5028
5029
5030class SimilarTo(Binary, Predicate):
5031    pass
5032
5033
5034class Slice(Binary):
5035    arg_types = {"this": False, "expression": False}
5036
5037
5038class Sub(Binary):
5039    pass
5040
5041
5042# Unary Expressions
5043# (NOT a)
5044class Unary(Condition):
5045    pass
5046
5047
5048class BitwiseNot(Unary):
5049    pass
5050
5051
5052class Not(Unary):
5053    pass
5054
5055
5056class Paren(Unary):
5057    @property
5058    def output_name(self) -> str:
5059        return self.this.name
5060
5061
5062class Neg(Unary):
5063    def to_py(self) -> int | Decimal:
5064        if self.is_number:
5065            return self.this.to_py() * -1
5066        return super().to_py()
5067
5068
5069class Alias(Expression):
5070    arg_types = {"this": True, "alias": False}
5071
5072    @property
5073    def output_name(self) -> str:
5074        return self.alias
5075
5076
5077# BigQuery requires the UNPIVOT column list aliases to be either strings or ints, but
5078# other dialects require identifiers. This enables us to transpile between them easily.
5079class PivotAlias(Alias):
5080    pass
5081
5082
5083# Represents Snowflake's ANY [ ORDER BY ... ] syntax
5084# https://docs.snowflake.com/en/sql-reference/constructs/pivot
5085class PivotAny(Expression):
5086    arg_types = {"this": False}
5087
5088
5089class Aliases(Expression):
5090    arg_types = {"this": True, "expressions": True}
5091
5092    @property
5093    def aliases(self):
5094        return self.expressions
5095
5096
5097# https://docs.aws.amazon.com/redshift/latest/dg/query-super.html
5098class AtIndex(Expression):
5099    arg_types = {"this": True, "expression": True}
5100
5101
5102class AtTimeZone(Expression):
5103    arg_types = {"this": True, "zone": True}
5104
5105
5106class FromTimeZone(Expression):
5107    arg_types = {"this": True, "zone": True}
5108
5109
5110class Between(Predicate):
5111    arg_types = {"this": True, "low": True, "high": True}
5112
5113
5114class Bracket(Condition):
5115    # https://cloud.google.com/bigquery/docs/reference/standard-sql/operators#array_subscript_operator
5116    arg_types = {
5117        "this": True,
5118        "expressions": True,
5119        "offset": False,
5120        "safe": False,
5121        "returns_list_for_maps": False,
5122    }
5123
5124    @property
5125    def output_name(self) -> str:
5126        if len(self.expressions) == 1:
5127            return self.expressions[0].output_name
5128
5129        return super().output_name
5130
5131
5132class Distinct(Expression):
5133    arg_types = {"expressions": False, "on": False}
5134
5135
5136class In(Predicate):
5137    arg_types = {
5138        "this": True,
5139        "expressions": False,
5140        "query": False,
5141        "unnest": False,
5142        "field": False,
5143        "is_global": False,
5144    }
5145
5146
5147# https://cloud.google.com/bigquery/docs/reference/standard-sql/procedural-language#for-in
5148class ForIn(Expression):
5149    arg_types = {"this": True, "expression": True}
5150
5151
5152class TimeUnit(Expression):
5153    """Automatically converts unit arg into a var."""
5154
5155    arg_types = {"unit": False}
5156
5157    UNABBREVIATED_UNIT_NAME = {
5158        "D": "DAY",
5159        "H": "HOUR",
5160        "M": "MINUTE",
5161        "MS": "MILLISECOND",
5162        "NS": "NANOSECOND",
5163        "Q": "QUARTER",
5164        "S": "SECOND",
5165        "US": "MICROSECOND",
5166        "W": "WEEK",
5167        "Y": "YEAR",
5168    }
5169
5170    VAR_LIKE = (Column, Literal, Var)
5171
5172    def __init__(self, **args):
5173        unit = args.get("unit")
5174        if isinstance(unit, self.VAR_LIKE):
5175            args["unit"] = Var(
5176                this=(self.UNABBREVIATED_UNIT_NAME.get(unit.name) or unit.name).upper()
5177            )
5178        elif isinstance(unit, Week):
5179            unit.set("this", Var(this=unit.this.name.upper()))
5180
5181        super().__init__(**args)
5182
5183    @property
5184    def unit(self) -> t.Optional[Var | IntervalSpan]:
5185        return self.args.get("unit")
5186
5187
5188class IntervalOp(TimeUnit):
5189    arg_types = {"unit": False, "expression": True}
5190
5191    def interval(self):
5192        return Interval(
5193            this=self.expression.copy(),
5194            unit=self.unit.copy() if self.unit else None,
5195        )
5196
5197
5198# https://www.oracletutorial.com/oracle-basics/oracle-interval/
5199# https://trino.io/docs/current/language/types.html#interval-day-to-second
5200# https://docs.databricks.com/en/sql/language-manual/data-types/interval-type.html
5201class IntervalSpan(DataType):
5202    arg_types = {"this": True, "expression": True}
5203
5204
5205class Interval(TimeUnit):
5206    arg_types = {"this": False, "unit": False}
5207
5208
5209class IgnoreNulls(Expression):
5210    pass
5211
5212
5213class RespectNulls(Expression):
5214    pass
5215
5216
5217# https://cloud.google.com/bigquery/docs/reference/standard-sql/aggregate-function-calls#max_min_clause
5218class HavingMax(Expression):
5219    arg_types = {"this": True, "expression": True, "max": True}
5220
5221
5222# Functions
5223class Func(Condition):
5224    """
5225    The base class for all function expressions.
5226
5227    Attributes:
5228        is_var_len_args (bool): if set to True the last argument defined in arg_types will be
5229            treated as a variable length argument and the argument's value will be stored as a list.
5230        _sql_names (list): the SQL name (1st item in the list) and aliases (subsequent items) for this
5231            function expression. These values are used to map this node to a name during parsing as
5232            well as to provide the function's name during SQL string generation. By default the SQL
5233            name is set to the expression's class name transformed to snake case.
5234    """
5235
5236    is_var_len_args = False
5237
5238    @classmethod
5239    def from_arg_list(cls, args):
5240        if cls.is_var_len_args:
5241            all_arg_keys = list(cls.arg_types)
5242            # If this function supports variable length argument treat the last argument as such.
5243            non_var_len_arg_keys = all_arg_keys[:-1] if cls.is_var_len_args else all_arg_keys
5244            num_non_var = len(non_var_len_arg_keys)
5245
5246            args_dict = {arg_key: arg for arg, arg_key in zip(args, non_var_len_arg_keys)}
5247            args_dict[all_arg_keys[-1]] = args[num_non_var:]
5248        else:
5249            args_dict = {arg_key: arg for arg, arg_key in zip(args, cls.arg_types)}
5250
5251        return cls(**args_dict)
5252
5253    @classmethod
5254    def sql_names(cls):
5255        if cls is Func:
5256            raise NotImplementedError(
5257                "SQL name is only supported by concrete function implementations"
5258            )
5259        if "_sql_names" not in cls.__dict__:
5260            cls._sql_names = [camel_to_snake_case(cls.__name__)]
5261        return cls._sql_names
5262
5263    @classmethod
5264    def sql_name(cls):
5265        return cls.sql_names()[0]
5266
5267    @classmethod
5268    def default_parser_mappings(cls):
5269        return {name: cls.from_arg_list for name in cls.sql_names()}
5270
5271
5272class AggFunc(Func):
5273    pass
5274
5275
5276class ParameterizedAgg(AggFunc):
5277    arg_types = {"this": True, "expressions": True, "params": True}
5278
5279
5280class Abs(Func):
5281    pass
5282
5283
5284class ArgMax(AggFunc):
5285    arg_types = {"this": True, "expression": True, "count": False}
5286    _sql_names = ["ARG_MAX", "ARGMAX", "MAX_BY"]
5287
5288
5289class ArgMin(AggFunc):
5290    arg_types = {"this": True, "expression": True, "count": False}
5291    _sql_names = ["ARG_MIN", "ARGMIN", "MIN_BY"]
5292
5293
5294class ApproxTopK(AggFunc):
5295    arg_types = {"this": True, "expression": False, "counters": False}
5296
5297
5298class Flatten(Func):
5299    pass
5300
5301
5302# https://spark.apache.org/docs/latest/api/sql/index.html#transform
5303class Transform(Func):
5304    arg_types = {"this": True, "expression": True}
5305
5306
5307class Anonymous(Func):
5308    arg_types = {"this": True, "expressions": False}
5309    is_var_len_args = True
5310
5311    @property
5312    def name(self) -> str:
5313        return self.this if isinstance(self.this, str) else self.this.name
5314
5315
5316class AnonymousAggFunc(AggFunc):
5317    arg_types = {"this": True, "expressions": False}
5318    is_var_len_args = True
5319
5320
5321# https://clickhouse.com/docs/en/sql-reference/aggregate-functions/combinators
5322class CombinedAggFunc(AnonymousAggFunc):
5323    arg_types = {"this": True, "expressions": False}
5324
5325
5326class CombinedParameterizedAgg(ParameterizedAgg):
5327    arg_types = {"this": True, "expressions": True, "params": True}
5328
5329
5330# https://docs.snowflake.com/en/sql-reference/functions/hll
5331# https://docs.aws.amazon.com/redshift/latest/dg/r_HLL_function.html
5332class Hll(AggFunc):
5333    arg_types = {"this": True, "expressions": False}
5334    is_var_len_args = True
5335
5336
5337class ApproxDistinct(AggFunc):
5338    arg_types = {"this": True, "accuracy": False}
5339    _sql_names = ["APPROX_DISTINCT", "APPROX_COUNT_DISTINCT"]
5340
5341
5342class Apply(Func):
5343    arg_types = {"this": True, "expression": True}
5344
5345
5346class Array(Func):
5347    arg_types = {"expressions": False, "bracket_notation": False}
5348    is_var_len_args = True
5349
5350
5351# https://docs.snowflake.com/en/sql-reference/functions/to_array
5352class ToArray(Func):
5353    pass
5354
5355
5356# https://materialize.com/docs/sql/types/list/
5357class List(Func):
5358    arg_types = {"expressions": False}
5359    is_var_len_args = True
5360
5361
5362# String pad, kind True -> LPAD, False -> RPAD
5363class Pad(Func):
5364    arg_types = {"this": True, "expression": True, "fill_pattern": False, "is_left": True}
5365
5366
5367# https://docs.snowflake.com/en/sql-reference/functions/to_char
5368# https://docs.oracle.com/en/database/oracle/oracle-database/23/sqlrf/TO_CHAR-number.html
5369class ToChar(Func):
5370    arg_types = {"this": True, "format": False, "nlsparam": False}
5371
5372
5373# https://docs.snowflake.com/en/sql-reference/functions/to_decimal
5374# https://docs.oracle.com/en/database/oracle/oracle-database/23/sqlrf/TO_NUMBER.html
5375class ToNumber(Func):
5376    arg_types = {
5377        "this": True,
5378        "format": False,
5379        "nlsparam": False,
5380        "precision": False,
5381        "scale": False,
5382    }
5383
5384
5385# https://docs.snowflake.com/en/sql-reference/functions/to_double
5386class ToDouble(Func):
5387    arg_types = {
5388        "this": True,
5389        "format": False,
5390    }
5391
5392
5393class Columns(Func):
5394    arg_types = {"this": True, "unpack": False}
5395
5396
5397# https://learn.microsoft.com/en-us/sql/t-sql/functions/cast-and-convert-transact-sql?view=sql-server-ver16#syntax
5398class Convert(Func):
5399    arg_types = {"this": True, "expression": True, "style": False}
5400
5401
5402class ConvertTimezone(Func):
5403    arg_types = {"source_tz": False, "target_tz": True, "timestamp": True}
5404
5405
5406class GenerateSeries(Func):
5407    arg_types = {"start": True, "end": True, "step": False, "is_end_exclusive": False}
5408
5409
5410# Postgres' GENERATE_SERIES function returns a row set, i.e. it implicitly explodes when it's
5411# used in a projection, so this expression is a helper that facilitates transpilation to other
5412# dialects. For example, we'd generate UNNEST(GENERATE_SERIES(...)) in DuckDB
5413class ExplodingGenerateSeries(GenerateSeries):
5414    pass
5415
5416
5417class ArrayAgg(AggFunc):
5418    arg_types = {"this": True, "nulls_excluded": False}
5419
5420
5421class ArrayUniqueAgg(AggFunc):
5422    pass
5423
5424
5425class ArrayAll(Func):
5426    arg_types = {"this": True, "expression": True}
5427
5428
5429# Represents Python's `any(f(x) for x in array)`, where `array` is `this` and `f` is `expression`
5430class ArrayAny(Func):
5431    arg_types = {"this": True, "expression": True}
5432
5433
5434class ArrayConcat(Func):
5435    _sql_names = ["ARRAY_CONCAT", "ARRAY_CAT"]
5436    arg_types = {"this": True, "expressions": False}
5437    is_var_len_args = True
5438
5439
5440class ArrayConstructCompact(Func):
5441    arg_types = {"expressions": True}
5442    is_var_len_args = True
5443
5444
5445class ArrayContains(Binary, Func):
5446    _sql_names = ["ARRAY_CONTAINS", "ARRAY_HAS"]
5447
5448
5449class ArrayContainsAll(Binary, Func):
5450    _sql_names = ["ARRAY_CONTAINS_ALL", "ARRAY_HAS_ALL"]
5451
5452
5453class ArrayFilter(Func):
5454    arg_types = {"this": True, "expression": True}
5455    _sql_names = ["FILTER", "ARRAY_FILTER"]
5456
5457
5458class ArrayToString(Func):
5459    arg_types = {"this": True, "expression": True, "null": False}
5460    _sql_names = ["ARRAY_TO_STRING", "ARRAY_JOIN"]
5461
5462
5463# https://cloud.google.com/bigquery/docs/reference/standard-sql/timestamp_functions#string
5464class String(Func):
5465    arg_types = {"this": True, "zone": False}
5466
5467
5468class StringToArray(Func):
5469    arg_types = {"this": True, "expression": True, "null": False}
5470    _sql_names = ["STRING_TO_ARRAY", "SPLIT_BY_STRING"]
5471
5472
5473class ArrayOverlaps(Binary, Func):
5474    pass
5475
5476
5477class ArraySize(Func):
5478    arg_types = {"this": True, "expression": False}
5479    _sql_names = ["ARRAY_SIZE", "ARRAY_LENGTH"]
5480
5481
5482class ArraySort(Func):
5483    arg_types = {"this": True, "expression": False}
5484
5485
5486class ArraySum(Func):
5487    arg_types = {"this": True, "expression": False}
5488
5489
5490class ArrayUnionAgg(AggFunc):
5491    pass
5492
5493
5494class Avg(AggFunc):
5495    pass
5496
5497
5498class AnyValue(AggFunc):
5499    pass
5500
5501
5502class Lag(AggFunc):
5503    arg_types = {"this": True, "offset": False, "default": False}
5504
5505
5506class Lead(AggFunc):
5507    arg_types = {"this": True, "offset": False, "default": False}
5508
5509
5510# some dialects have a distinction between first and first_value, usually first is an aggregate func
5511# and first_value is a window func
5512class First(AggFunc):
5513    pass
5514
5515
5516class Last(AggFunc):
5517    pass
5518
5519
5520class FirstValue(AggFunc):
5521    pass
5522
5523
5524class LastValue(AggFunc):
5525    pass
5526
5527
5528class NthValue(AggFunc):
5529    arg_types = {"this": True, "offset": True}
5530
5531
5532class Case(Func):
5533    arg_types = {"this": False, "ifs": True, "default": False}
5534
5535    def when(self, condition: ExpOrStr, then: ExpOrStr, copy: bool = True, **opts) -> Case:
5536        instance = maybe_copy(self, copy)
5537        instance.append(
5538            "ifs",
5539            If(
5540                this=maybe_parse(condition, copy=copy, **opts),
5541                true=maybe_parse(then, copy=copy, **opts),
5542            ),
5543        )
5544        return instance
5545
5546    def else_(self, condition: ExpOrStr, copy: bool = True, **opts) -> Case:
5547        instance = maybe_copy(self, copy)
5548        instance.set("default", maybe_parse(condition, copy=copy, **opts))
5549        return instance
5550
5551
5552class Cast(Func):
5553    arg_types = {
5554        "this": True,
5555        "to": True,
5556        "format": False,
5557        "safe": False,
5558        "action": False,
5559        "default": False,
5560    }
5561
5562    @property
5563    def name(self) -> str:
5564        return self.this.name
5565
5566    @property
5567    def to(self) -> DataType:
5568        return self.args["to"]
5569
5570    @property
5571    def output_name(self) -> str:
5572        return self.name
5573
5574    def is_type(self, *dtypes: DATA_TYPE) -> bool:
5575        """
5576        Checks whether this Cast's DataType matches one of the provided data types. Nested types
5577        like arrays or structs will be compared using "structural equivalence" semantics, so e.g.
5578        array<int> != array<float>.
5579
5580        Args:
5581            dtypes: the data types to compare this Cast's DataType to.
5582
5583        Returns:
5584            True, if and only if there is a type in `dtypes` which is equal to this Cast's DataType.
5585        """
5586        return self.to.is_type(*dtypes)
5587
5588
5589class TryCast(Cast):
5590    pass
5591
5592
5593# https://clickhouse.com/docs/sql-reference/data-types/newjson#reading-json-paths-as-sub-columns
5594class JSONCast(Cast):
5595    pass
5596
5597
5598class Try(Func):
5599    pass
5600
5601
5602class CastToStrType(Func):
5603    arg_types = {"this": True, "to": True}
5604
5605
5606class Collate(Binary, Func):
5607    pass
5608
5609
5610class Ceil(Func):
5611    arg_types = {"this": True, "decimals": False, "to": False}
5612    _sql_names = ["CEIL", "CEILING"]
5613
5614
5615class Coalesce(Func):
5616    arg_types = {"this": True, "expressions": False, "is_nvl": False}
5617    is_var_len_args = True
5618    _sql_names = ["COALESCE", "IFNULL", "NVL"]
5619
5620
5621class Chr(Func):
5622    arg_types = {"expressions": True, "charset": False}
5623    is_var_len_args = True
5624    _sql_names = ["CHR", "CHAR"]
5625
5626
5627class Concat(Func):
5628    arg_types = {"expressions": True, "safe": False, "coalesce": False}
5629    is_var_len_args = True
5630
5631
5632class ConcatWs(Concat):
5633    _sql_names = ["CONCAT_WS"]
5634
5635
5636class Contains(Func):
5637    arg_types = {"this": True, "expression": True}
5638
5639
5640# https://docs.oracle.com/cd/B13789_01/server.101/b10759/operators004.htm#i1035022
5641class ConnectByRoot(Func):
5642    pass
5643
5644
5645class Count(AggFunc):
5646    arg_types = {"this": False, "expressions": False, "big_int": False}
5647    is_var_len_args = True
5648
5649
5650class CountIf(AggFunc):
5651    _sql_names = ["COUNT_IF", "COUNTIF"]
5652
5653
5654# cube root
5655class Cbrt(Func):
5656    pass
5657
5658
5659class CurrentDate(Func):
5660    arg_types = {"this": False}
5661
5662
5663class CurrentDatetime(Func):
5664    arg_types = {"this": False}
5665
5666
5667class CurrentTime(Func):
5668    arg_types = {"this": False}
5669
5670
5671class CurrentTimestamp(Func):
5672    arg_types = {"this": False, "sysdate": False}
5673
5674
5675class CurrentSchema(Func):
5676    arg_types = {"this": False}
5677
5678
5679class CurrentUser(Func):
5680    arg_types = {"this": False}
5681
5682
5683class DateAdd(Func, IntervalOp):
5684    arg_types = {"this": True, "expression": True, "unit": False}
5685
5686
5687class DateBin(Func, IntervalOp):
5688    arg_types = {"this": True, "expression": True, "unit": False, "zone": False}
5689
5690
5691class DateSub(Func, IntervalOp):
5692    arg_types = {"this": True, "expression": True, "unit": False}
5693
5694
5695class DateDiff(Func, TimeUnit):
5696    _sql_names = ["DATEDIFF", "DATE_DIFF"]
5697    arg_types = {"this": True, "expression": True, "unit": False}
5698
5699
5700class DateTrunc(Func):
5701    arg_types = {"unit": True, "this": True, "zone": False}
5702
5703    def __init__(self, **args):
5704        # Across most dialects it's safe to unabbreviate the unit (e.g. 'Q' -> 'QUARTER') except Oracle
5705        # https://docs.oracle.com/en/database/oracle/oracle-database/21/sqlrf/ROUND-and-TRUNC-Date-Functions.html
5706        unabbreviate = args.pop("unabbreviate", True)
5707
5708        unit = args.get("unit")
5709        if isinstance(unit, TimeUnit.VAR_LIKE):
5710            unit_name = unit.name.upper()
5711            if unabbreviate and unit_name in TimeUnit.UNABBREVIATED_UNIT_NAME:
5712                unit_name = TimeUnit.UNABBREVIATED_UNIT_NAME[unit_name]
5713
5714            args["unit"] = Literal.string(unit_name)
5715        elif isinstance(unit, Week):
5716            unit.set("this", Literal.string(unit.this.name.upper()))
5717
5718        super().__init__(**args)
5719
5720    @property
5721    def unit(self) -> Expression:
5722        return self.args["unit"]
5723
5724
5725# https://cloud.google.com/bigquery/docs/reference/standard-sql/datetime_functions#datetime
5726# expression can either be time_expr or time_zone
5727class Datetime(Func):
5728    arg_types = {"this": True, "expression": False}
5729
5730
5731class DatetimeAdd(Func, IntervalOp):
5732    arg_types = {"this": True, "expression": True, "unit": False}
5733
5734
5735class DatetimeSub(Func, IntervalOp):
5736    arg_types = {"this": True, "expression": True, "unit": False}
5737
5738
5739class DatetimeDiff(Func, TimeUnit):
5740    arg_types = {"this": True, "expression": True, "unit": False}
5741
5742
5743class DatetimeTrunc(Func, TimeUnit):
5744    arg_types = {"this": True, "unit": True, "zone": False}
5745
5746
5747class DayOfWeek(Func):
5748    _sql_names = ["DAY_OF_WEEK", "DAYOFWEEK"]
5749
5750
5751# https://duckdb.org/docs/sql/functions/datepart.html#part-specifiers-only-usable-as-date-part-specifiers
5752# ISO day of week function in duckdb is ISODOW
5753class DayOfWeekIso(Func):
5754    _sql_names = ["DAYOFWEEK_ISO", "ISODOW"]
5755
5756
5757class DayOfMonth(Func):
5758    _sql_names = ["DAY_OF_MONTH", "DAYOFMONTH"]
5759
5760
5761class DayOfYear(Func):
5762    _sql_names = ["DAY_OF_YEAR", "DAYOFYEAR"]
5763
5764
5765class ToDays(Func):
5766    pass
5767
5768
5769class WeekOfYear(Func):
5770    _sql_names = ["WEEK_OF_YEAR", "WEEKOFYEAR"]
5771
5772
5773class MonthsBetween(Func):
5774    arg_types = {"this": True, "expression": True, "roundoff": False}
5775
5776
5777class MakeInterval(Func):
5778    arg_types = {
5779        "year": False,
5780        "month": False,
5781        "day": False,
5782        "hour": False,
5783        "minute": False,
5784        "second": False,
5785    }
5786
5787
5788class LastDay(Func, TimeUnit):
5789    _sql_names = ["LAST_DAY", "LAST_DAY_OF_MONTH"]
5790    arg_types = {"this": True, "unit": False}
5791
5792
5793class Extract(Func):
5794    arg_types = {"this": True, "expression": True}
5795
5796
5797class Exists(Func, SubqueryPredicate):
5798    arg_types = {"this": True, "expression": False}
5799
5800
5801class Timestamp(Func):
5802    arg_types = {"this": False, "zone": False, "with_tz": False}
5803
5804
5805class TimestampAdd(Func, TimeUnit):
5806    arg_types = {"this": True, "expression": True, "unit": False}
5807
5808
5809class TimestampSub(Func, TimeUnit):
5810    arg_types = {"this": True, "expression": True, "unit": False}
5811
5812
5813class TimestampDiff(Func, TimeUnit):
5814    _sql_names = ["TIMESTAMPDIFF", "TIMESTAMP_DIFF"]
5815    arg_types = {"this": True, "expression": True, "unit": False}
5816
5817
5818class TimestampTrunc(Func, TimeUnit):
5819    arg_types = {"this": True, "unit": True, "zone": False}
5820
5821
5822class TimeAdd(Func, TimeUnit):
5823    arg_types = {"this": True, "expression": True, "unit": False}
5824
5825
5826class TimeSub(Func, TimeUnit):
5827    arg_types = {"this": True, "expression": True, "unit": False}
5828
5829
5830class TimeDiff(Func, TimeUnit):
5831    arg_types = {"this": True, "expression": True, "unit": False}
5832
5833
5834class TimeTrunc(Func, TimeUnit):
5835    arg_types = {"this": True, "unit": True, "zone": False}
5836
5837
5838class DateFromParts(Func):
5839    _sql_names = ["DATE_FROM_PARTS", "DATEFROMPARTS"]
5840    arg_types = {"year": True, "month": True, "day": True}
5841
5842
5843class TimeFromParts(Func):
5844    _sql_names = ["TIME_FROM_PARTS", "TIMEFROMPARTS"]
5845    arg_types = {
5846        "hour": True,
5847        "min": True,
5848        "sec": True,
5849        "nano": False,
5850        "fractions": False,
5851        "precision": False,
5852    }
5853
5854
5855class DateStrToDate(Func):
5856    pass
5857
5858
5859class DateToDateStr(Func):
5860    pass
5861
5862
5863class DateToDi(Func):
5864    pass
5865
5866
5867# https://cloud.google.com/bigquery/docs/reference/standard-sql/date_functions#date
5868class Date(Func):
5869    arg_types = {"this": False, "zone": False, "expressions": False}
5870    is_var_len_args = True
5871
5872
5873class Day(Func):
5874    pass
5875
5876
5877class Decode(Func):
5878    arg_types = {"this": True, "charset": True, "replace": False}
5879
5880
5881class DiToDate(Func):
5882    pass
5883
5884
5885class Encode(Func):
5886    arg_types = {"this": True, "charset": True}
5887
5888
5889class Exp(Func):
5890    pass
5891
5892
5893# https://docs.snowflake.com/en/sql-reference/functions/flatten
5894class Explode(Func, UDTF):
5895    arg_types = {"this": True, "expressions": False}
5896    is_var_len_args = True
5897
5898
5899# https://spark.apache.org/docs/latest/api/sql/#inline
5900class Inline(Func):
5901    pass
5902
5903
5904class ExplodeOuter(Explode):
5905    pass
5906
5907
5908class Posexplode(Explode):
5909    pass
5910
5911
5912class PosexplodeOuter(Posexplode, ExplodeOuter):
5913    pass
5914
5915
5916class Unnest(Func, UDTF):
5917    arg_types = {
5918        "expressions": True,
5919        "alias": False,
5920        "offset": False,
5921        "explode_array": False,
5922    }
5923
5924    @property
5925    def selects(self) -> t.List[Expression]:
5926        columns = super().selects
5927        offset = self.args.get("offset")
5928        if offset:
5929            columns = columns + [to_identifier("offset") if offset is True else offset]
5930        return columns
5931
5932
5933class Floor(Func):
5934    arg_types = {"this": True, "decimals": False, "to": False}
5935
5936
5937class FromBase64(Func):
5938    pass
5939
5940
5941class FeaturesAtTime(Func):
5942    arg_types = {"this": True, "time": False, "num_rows": False, "ignore_feature_nulls": False}
5943
5944
5945class ToBase64(Func):
5946    pass
5947
5948
5949# https://trino.io/docs/current/functions/datetime.html#from_iso8601_timestamp
5950class FromISO8601Timestamp(Func):
5951    _sql_names = ["FROM_ISO8601_TIMESTAMP"]
5952
5953
5954class GapFill(Func):
5955    arg_types = {
5956        "this": True,
5957        "ts_column": True,
5958        "bucket_width": True,
5959        "partitioning_columns": False,
5960        "value_columns": False,
5961        "origin": False,
5962        "ignore_nulls": False,
5963    }
5964
5965
5966# https://cloud.google.com/bigquery/docs/reference/standard-sql/array_functions#generate_date_array
5967class GenerateDateArray(Func):
5968    arg_types = {"start": True, "end": True, "step": False}
5969
5970
5971# https://cloud.google.com/bigquery/docs/reference/standard-sql/array_functions#generate_timestamp_array
5972class GenerateTimestampArray(Func):
5973    arg_types = {"start": True, "end": True, "step": True}
5974
5975
5976class Greatest(Func):
5977    arg_types = {"this": True, "expressions": False}
5978    is_var_len_args = True
5979
5980
5981# Trino's `ON OVERFLOW TRUNCATE [filler_string] {WITH | WITHOUT} COUNT`
5982# https://trino.io/docs/current/functions/aggregate.html#listagg
5983class OverflowTruncateBehavior(Expression):
5984    arg_types = {"this": False, "with_count": True}
5985
5986
5987class GroupConcat(AggFunc):
5988    arg_types = {"this": True, "separator": False, "on_overflow": False}
5989
5990
5991class Hex(Func):
5992    pass
5993
5994
5995class LowerHex(Hex):
5996    pass
5997
5998
5999class And(Connector, Func):
6000    pass
6001
6002
6003class Or(Connector, Func):
6004    pass
6005
6006
6007class Xor(Connector, Func):
6008    arg_types = {"this": False, "expression": False, "expressions": False}
6009
6010
6011class If(Func):
6012    arg_types = {"this": True, "true": True, "false": False}
6013    _sql_names = ["IF", "IIF"]
6014
6015
6016class Nullif(Func):
6017    arg_types = {"this": True, "expression": True}
6018
6019
6020class Initcap(Func):
6021    arg_types = {"this": True, "expression": False}
6022
6023
6024class IsAscii(Func):
6025    pass
6026
6027
6028class IsNan(Func):
6029    _sql_names = ["IS_NAN", "ISNAN"]
6030
6031
6032# https://cloud.google.com/bigquery/docs/reference/standard-sql/json_functions#int64_for_json
6033class Int64(Func):
6034    pass
6035
6036
6037class IsInf(Func):
6038    _sql_names = ["IS_INF", "ISINF"]
6039
6040
6041# https://www.postgresql.org/docs/current/functions-json.html
6042class JSON(Expression):
6043    arg_types = {"this": False, "with": False, "unique": False}
6044
6045
6046class JSONPath(Expression):
6047    arg_types = {"expressions": True, "escape": False}
6048
6049    @property
6050    def output_name(self) -> str:
6051        last_segment = self.expressions[-1].this
6052        return last_segment if isinstance(last_segment, str) else ""
6053
6054
6055class JSONPathPart(Expression):
6056    arg_types = {}
6057
6058
6059class JSONPathFilter(JSONPathPart):
6060    arg_types = {"this": True}
6061
6062
6063class JSONPathKey(JSONPathPart):
6064    arg_types = {"this": True}
6065
6066
6067class JSONPathRecursive(JSONPathPart):
6068    arg_types = {"this": False}
6069
6070
6071class JSONPathRoot(JSONPathPart):
6072    pass
6073
6074
6075class JSONPathScript(JSONPathPart):
6076    arg_types = {"this": True}
6077
6078
6079class JSONPathSlice(JSONPathPart):
6080    arg_types = {"start": False, "end": False, "step": False}
6081
6082
6083class JSONPathSelector(JSONPathPart):
6084    arg_types = {"this": True}
6085
6086
6087class JSONPathSubscript(JSONPathPart):
6088    arg_types = {"this": True}
6089
6090
6091class JSONPathUnion(JSONPathPart):
6092    arg_types = {"expressions": True}
6093
6094
6095class JSONPathWildcard(JSONPathPart):
6096    pass
6097
6098
6099class FormatJson(Expression):
6100    pass
6101
6102
6103class JSONKeyValue(Expression):
6104    arg_types = {"this": True, "expression": True}
6105
6106
6107class JSONObject(Func):
6108    arg_types = {
6109        "expressions": False,
6110        "null_handling": False,
6111        "unique_keys": False,
6112        "return_type": False,
6113        "encoding": False,
6114    }
6115
6116
6117class JSONObjectAgg(AggFunc):
6118    arg_types = {
6119        "expressions": False,
6120        "null_handling": False,
6121        "unique_keys": False,
6122        "return_type": False,
6123        "encoding": False,
6124    }
6125
6126
6127# https://www.postgresql.org/docs/9.5/functions-aggregate.html
6128class JSONBObjectAgg(AggFunc):
6129    arg_types = {"this": True, "expression": True}
6130
6131
6132# https://docs.oracle.com/en/database/oracle/oracle-database/19/sqlrf/JSON_ARRAY.html
6133class JSONArray(Func):
6134    arg_types = {
6135        "expressions": True,
6136        "null_handling": False,
6137        "return_type": False,
6138        "strict": False,
6139    }
6140
6141
6142# https://docs.oracle.com/en/database/oracle/oracle-database/19/sqlrf/JSON_ARRAYAGG.html
6143class JSONArrayAgg(Func):
6144    arg_types = {
6145        "this": True,
6146        "order": False,
6147        "null_handling": False,
6148        "return_type": False,
6149        "strict": False,
6150    }
6151
6152
6153class JSONExists(Func):
6154    arg_types = {"this": True, "path": True, "passing": False, "on_condition": False}
6155
6156
6157# https://docs.oracle.com/en/database/oracle/oracle-database/19/sqlrf/JSON_TABLE.html
6158# Note: parsing of JSON column definitions is currently incomplete.
6159class JSONColumnDef(Expression):
6160    arg_types = {"this": False, "kind": False, "path": False, "nested_schema": False}
6161
6162
6163class JSONSchema(Expression):
6164    arg_types = {"expressions": True}
6165
6166
6167# https://dev.mysql.com/doc/refman/8.4/en/json-search-functions.html#function_json-value
6168class JSONValue(Expression):
6169    arg_types = {
6170        "this": True,
6171        "path": True,
6172        "returning": False,
6173        "on_condition": False,
6174    }
6175
6176
6177class JSONValueArray(Func):
6178    arg_types = {"this": True, "expression": False}
6179
6180
6181# # https://docs.oracle.com/en/database/oracle/oracle-database/19/sqlrf/JSON_TABLE.html
6182class JSONTable(Func):
6183    arg_types = {
6184        "this": True,
6185        "schema": True,
6186        "path": False,
6187        "error_handling": False,
6188        "empty_handling": False,
6189    }
6190
6191
6192# https://docs.snowflake.com/en/sql-reference/functions/object_insert
6193class ObjectInsert(Func):
6194    arg_types = {
6195        "this": True,
6196        "key": True,
6197        "value": True,
6198        "update_flag": False,
6199    }
6200
6201
6202class OpenJSONColumnDef(Expression):
6203    arg_types = {"this": True, "kind": True, "path": False, "as_json": False}
6204
6205
6206class OpenJSON(Func):
6207    arg_types = {"this": True, "path": False, "expressions": False}
6208
6209
6210class JSONBContains(Binary, Func):
6211    _sql_names = ["JSONB_CONTAINS"]
6212
6213
6214class JSONBExists(Func):
6215    arg_types = {"this": True, "path": True}
6216    _sql_names = ["JSONB_EXISTS"]
6217
6218
6219class JSONExtract(Binary, Func):
6220    arg_types = {
6221        "this": True,
6222        "expression": True,
6223        "only_json_types": False,
6224        "expressions": False,
6225        "variant_extract": False,
6226        "json_query": False,
6227        "option": False,
6228        "quote": False,
6229        "on_condition": False,
6230    }
6231    _sql_names = ["JSON_EXTRACT"]
6232    is_var_len_args = True
6233
6234    @property
6235    def output_name(self) -> str:
6236        return self.expression.output_name if not self.expressions else ""
6237
6238
6239# https://trino.io/docs/current/functions/json.html#json-query
6240class JSONExtractQuote(Expression):
6241    arg_types = {
6242        "option": True,
6243        "scalar": False,
6244    }
6245
6246
6247class JSONExtractArray(Func):
6248    arg_types = {"this": True, "expression": False}
6249    _sql_names = ["JSON_EXTRACT_ARRAY"]
6250
6251
6252class JSONExtractScalar(Binary, Func):
6253    arg_types = {"this": True, "expression": True, "only_json_types": False, "expressions": False}
6254    _sql_names = ["JSON_EXTRACT_SCALAR"]
6255    is_var_len_args = True
6256
6257    @property
6258    def output_name(self) -> str:
6259        return self.expression.output_name
6260
6261
6262class JSONBExtract(Binary, Func):
6263    _sql_names = ["JSONB_EXTRACT"]
6264
6265
6266class JSONBExtractScalar(Binary, Func):
6267    _sql_names = ["JSONB_EXTRACT_SCALAR"]
6268
6269
6270class JSONFormat(Func):
6271    arg_types = {"this": False, "options": False}
6272    _sql_names = ["JSON_FORMAT"]
6273
6274
6275# https://dev.mysql.com/doc/refman/8.0/en/json-search-functions.html#operator_member-of
6276class JSONArrayContains(Binary, Predicate, Func):
6277    _sql_names = ["JSON_ARRAY_CONTAINS"]
6278
6279
6280class ParseJSON(Func):
6281    # BigQuery, Snowflake have PARSE_JSON, Presto has JSON_PARSE
6282    # Snowflake also has TRY_PARSE_JSON, which is represented using `safe`
6283    _sql_names = ["PARSE_JSON", "JSON_PARSE"]
6284    arg_types = {"this": True, "expression": False, "safe": False}
6285
6286
6287class Least(Func):
6288    arg_types = {"this": True, "expressions": False}
6289    is_var_len_args = True
6290
6291
6292class Left(Func):
6293    arg_types = {"this": True, "expression": True}
6294
6295
6296class Right(Func):
6297    arg_types = {"this": True, "expression": True}
6298
6299
6300class Length(Func):
6301    arg_types = {"this": True, "binary": False, "encoding": False}
6302    _sql_names = ["LENGTH", "LEN", "CHAR_LENGTH", "CHARACTER_LENGTH"]
6303
6304
6305class Levenshtein(Func):
6306    arg_types = {
6307        "this": True,
6308        "expression": False,
6309        "ins_cost": False,
6310        "del_cost": False,
6311        "sub_cost": False,
6312        "max_dist": False,
6313    }
6314
6315
6316class Ln(Func):
6317    pass
6318
6319
6320class Log(Func):
6321    arg_types = {"this": True, "expression": False}
6322
6323
6324class LogicalOr(AggFunc):
6325    _sql_names = ["LOGICAL_OR", "BOOL_OR", "BOOLOR_AGG"]
6326
6327
6328class LogicalAnd(AggFunc):
6329    _sql_names = ["LOGICAL_AND", "BOOL_AND", "BOOLAND_AGG"]
6330
6331
6332class Lower(Func):
6333    _sql_names = ["LOWER", "LCASE"]
6334
6335
6336class Map(Func):
6337    arg_types = {"keys": False, "values": False}
6338
6339    @property
6340    def keys(self) -> t.List[Expression]:
6341        keys = self.args.get("keys")
6342        return keys.expressions if keys else []
6343
6344    @property
6345    def values(self) -> t.List[Expression]:
6346        values = self.args.get("values")
6347        return values.expressions if values else []
6348
6349
6350# Represents the MAP {...} syntax in DuckDB - basically convert a struct to a MAP
6351class ToMap(Func):
6352    pass
6353
6354
6355class MapFromEntries(Func):
6356    pass
6357
6358
6359# https://learn.microsoft.com/en-us/sql/t-sql/language-elements/scope-resolution-operator-transact-sql?view=sql-server-ver16
6360class ScopeResolution(Expression):
6361    arg_types = {"this": False, "expression": True}
6362
6363
6364class Stream(Expression):
6365    pass
6366
6367
6368class StarMap(Func):
6369    pass
6370
6371
6372class VarMap(Func):
6373    arg_types = {"keys": True, "values": True}
6374    is_var_len_args = True
6375
6376    @property
6377    def keys(self) -> t.List[Expression]:
6378        return self.args["keys"].expressions
6379
6380    @property
6381    def values(self) -> t.List[Expression]:
6382        return self.args["values"].expressions
6383
6384
6385# https://dev.mysql.com/doc/refman/8.0/en/fulltext-search.html
6386class MatchAgainst(Func):
6387    arg_types = {"this": True, "expressions": True, "modifier": False}
6388
6389
6390class Max(AggFunc):
6391    arg_types = {"this": True, "expressions": False}
6392    is_var_len_args = True
6393
6394
6395class MD5(Func):
6396    _sql_names = ["MD5"]
6397
6398
6399# Represents the variant of the MD5 function that returns a binary value
6400class MD5Digest(Func):
6401    _sql_names = ["MD5_DIGEST"]
6402
6403
6404class Median(AggFunc):
6405    pass
6406
6407
6408class Min(AggFunc):
6409    arg_types = {"this": True, "expressions": False}
6410    is_var_len_args = True
6411
6412
6413class Month(Func):
6414    pass
6415
6416
6417class AddMonths(Func):
6418    arg_types = {"this": True, "expression": True}
6419
6420
6421class Nvl2(Func):
6422    arg_types = {"this": True, "true": True, "false": False}
6423
6424
6425class Normalize(Func):
6426    arg_types = {"this": True, "form": False}
6427
6428
6429class Overlay(Func):
6430    arg_types = {"this": True, "expression": True, "from": True, "for": False}
6431
6432
6433# https://cloud.google.com/bigquery/docs/reference/standard-sql/bigqueryml-syntax-predict#mlpredict_function
6434class Predict(Func):
6435    arg_types = {"this": True, "expression": True, "params_struct": False}
6436
6437
6438class Pow(Binary, Func):
6439    _sql_names = ["POWER", "POW"]
6440
6441
6442class PercentileCont(AggFunc):
6443    arg_types = {"this": True, "expression": False}
6444
6445
6446class PercentileDisc(AggFunc):
6447    arg_types = {"this": True, "expression": False}
6448
6449
6450class Quantile(AggFunc):
6451    arg_types = {"this": True, "quantile": True}
6452
6453
6454class ApproxQuantile(Quantile):
6455    arg_types = {"this": True, "quantile": True, "accuracy": False, "weight": False}
6456
6457
6458class Quarter(Func):
6459    pass
6460
6461
6462# https://docs.teradata.com/r/Enterprise_IntelliFlex_VMware/SQL-Functions-Expressions-and-Predicates/Arithmetic-Trigonometric-Hyperbolic-Operators/Functions/RANDOM/RANDOM-Function-Syntax
6463# teradata lower and upper bounds
6464class Rand(Func):
6465    _sql_names = ["RAND", "RANDOM"]
6466    arg_types = {"this": False, "lower": False, "upper": False}
6467
6468
6469class Randn(Func):
6470    arg_types = {"this": False}
6471
6472
6473class RangeN(Func):
6474    arg_types = {"this": True, "expressions": True, "each": False}
6475
6476
6477class ReadCSV(Func):
6478    _sql_names = ["READ_CSV"]
6479    is_var_len_args = True
6480    arg_types = {"this": True, "expressions": False}
6481
6482
6483class Reduce(Func):
6484    arg_types = {"this": True, "initial": True, "merge": True, "finish": False}
6485
6486
6487class RegexpExtract(Func):
6488    arg_types = {
6489        "this": True,
6490        "expression": True,
6491        "position": False,
6492        "occurrence": False,
6493        "parameters": False,
6494        "group": False,
6495    }
6496
6497
6498class RegexpExtractAll(Func):
6499    arg_types = {
6500        "this": True,
6501        "expression": True,
6502        "position": False,
6503        "occurrence": False,
6504        "parameters": False,
6505        "group": False,
6506    }
6507
6508
6509class RegexpReplace(Func):
6510    arg_types = {
6511        "this": True,
6512        "expression": True,
6513        "replacement": False,
6514        "position": False,
6515        "occurrence": False,
6516        "modifiers": False,
6517    }
6518
6519
6520class RegexpLike(Binary, Func):
6521    arg_types = {"this": True, "expression": True, "flag": False}
6522
6523
6524class RegexpILike(Binary, Func):
6525    arg_types = {"this": True, "expression": True, "flag": False}
6526
6527
6528# https://spark.apache.org/docs/latest/api/python/reference/pyspark.sql/api/pyspark.sql.functions.split.html
6529# limit is the number of times a pattern is applied
6530class RegexpSplit(Func):
6531    arg_types = {"this": True, "expression": True, "limit": False}
6532
6533
6534class Repeat(Func):
6535    arg_types = {"this": True, "times": True}
6536
6537
6538# https://learn.microsoft.com/en-us/sql/t-sql/functions/round-transact-sql?view=sql-server-ver16
6539# tsql third argument function == trunctaion if not 0
6540class Round(Func):
6541    arg_types = {"this": True, "decimals": False, "truncate": False}
6542
6543
6544class RowNumber(Func):
6545    arg_types = {"this": False}
6546
6547
6548class SafeDivide(Func):
6549    arg_types = {"this": True, "expression": True}
6550
6551
6552class SHA(Func):
6553    _sql_names = ["SHA", "SHA1"]
6554
6555
6556class SHA2(Func):
6557    _sql_names = ["SHA2"]
6558    arg_types = {"this": True, "length": False}
6559
6560
6561class Sign(Func):
6562    _sql_names = ["SIGN", "SIGNUM"]
6563
6564
6565class SortArray(Func):
6566    arg_types = {"this": True, "asc": False}
6567
6568
6569class Split(Func):
6570    arg_types = {"this": True, "expression": True, "limit": False}
6571
6572
6573# https://spark.apache.org/docs/latest/api/python/reference/pyspark.sql/api/pyspark.sql.functions.split_part.html
6574class SplitPart(Func):
6575    arg_types = {"this": True, "delimiter": True, "part_index": True}
6576
6577
6578# Start may be omitted in the case of postgres
6579# https://www.postgresql.org/docs/9.1/functions-string.html @ Table 9-6
6580class Substring(Func):
6581    _sql_names = ["SUBSTRING", "SUBSTR"]
6582    arg_types = {"this": True, "start": False, "length": False}
6583
6584
6585class StandardHash(Func):
6586    arg_types = {"this": True, "expression": False}
6587
6588
6589class StartsWith(Func):
6590    _sql_names = ["STARTS_WITH", "STARTSWITH"]
6591    arg_types = {"this": True, "expression": True}
6592
6593
6594class StrPosition(Func):
6595    arg_types = {
6596        "this": True,
6597        "substr": True,
6598        "position": False,
6599        "occurrence": False,
6600    }
6601
6602
6603class StrToDate(Func):
6604    arg_types = {"this": True, "format": False, "safe": False}
6605
6606
6607class StrToTime(Func):
6608    arg_types = {"this": True, "format": True, "zone": False, "safe": False}
6609
6610
6611# Spark allows unix_timestamp()
6612# https://spark.apache.org/docs/3.1.3/api/python/reference/api/pyspark.sql.functions.unix_timestamp.html
6613class StrToUnix(Func):
6614    arg_types = {"this": False, "format": False}
6615
6616
6617# https://prestodb.io/docs/current/functions/string.html
6618# https://spark.apache.org/docs/latest/api/sql/index.html#str_to_map
6619class StrToMap(Func):
6620    arg_types = {
6621        "this": True,
6622        "pair_delim": False,
6623        "key_value_delim": False,
6624        "duplicate_resolution_callback": False,
6625    }
6626
6627
6628class NumberToStr(Func):
6629    arg_types = {"this": True, "format": True, "culture": False}
6630
6631
6632class FromBase(Func):
6633    arg_types = {"this": True, "expression": True}
6634
6635
6636class Struct(Func):
6637    arg_types = {"expressions": False}
6638    is_var_len_args = True
6639
6640
6641class StructExtract(Func):
6642    arg_types = {"this": True, "expression": True}
6643
6644
6645# https://learn.microsoft.com/en-us/sql/t-sql/functions/stuff-transact-sql?view=sql-server-ver16
6646# https://docs.snowflake.com/en/sql-reference/functions/insert
6647class Stuff(Func):
6648    _sql_names = ["STUFF", "INSERT"]
6649    arg_types = {"this": True, "start": True, "length": True, "expression": True}
6650
6651
6652class Sum(AggFunc):
6653    pass
6654
6655
6656class Sqrt(Func):
6657    pass
6658
6659
6660class Stddev(AggFunc):
6661    _sql_names = ["STDDEV", "STDEV"]
6662
6663
6664class StddevPop(AggFunc):
6665    pass
6666
6667
6668class StddevSamp(AggFunc):
6669    pass
6670
6671
6672# https://cloud.google.com/bigquery/docs/reference/standard-sql/time_functions#time
6673class Time(Func):
6674    arg_types = {"this": False, "zone": False}
6675
6676
6677class TimeToStr(Func):
6678    arg_types = {"this": True, "format": True, "culture": False, "zone": False}
6679
6680
6681class TimeToTimeStr(Func):
6682    pass
6683
6684
6685class TimeToUnix(Func):
6686    pass
6687
6688
6689class TimeStrToDate(Func):
6690    pass
6691
6692
6693class TimeStrToTime(Func):
6694    arg_types = {"this": True, "zone": False}
6695
6696
6697class TimeStrToUnix(Func):
6698    pass
6699
6700
6701class Trim(Func):
6702    arg_types = {
6703        "this": True,
6704        "expression": False,
6705        "position": False,
6706        "collation": False,
6707    }
6708
6709
6710class TsOrDsAdd(Func, TimeUnit):
6711    # return_type is used to correctly cast the arguments of this expression when transpiling it
6712    arg_types = {"this": True, "expression": True, "unit": False, "return_type": False}
6713
6714    @property
6715    def return_type(self) -> DataType:
6716        return DataType.build(self.args.get("return_type") or DataType.Type.DATE)
6717
6718
6719class TsOrDsDiff(Func, TimeUnit):
6720    arg_types = {"this": True, "expression": True, "unit": False}
6721
6722
6723class TsOrDsToDateStr(Func):
6724    pass
6725
6726
6727class TsOrDsToDate(Func):
6728    arg_types = {"this": True, "format": False, "safe": False}
6729
6730
6731class TsOrDsToDatetime(Func):
6732    pass
6733
6734
6735class TsOrDsToTime(Func):
6736    arg_types = {"this": True, "format": False, "safe": False}
6737
6738
6739class TsOrDsToTimestamp(Func):
6740    pass
6741
6742
6743class TsOrDiToDi(Func):
6744    pass
6745
6746
6747class Unhex(Func):
6748    arg_types = {"this": True, "expression": False}
6749
6750
6751class Unicode(Func):
6752    pass
6753
6754
6755# https://cloud.google.com/bigquery/docs/reference/standard-sql/date_functions#unix_date
6756class UnixDate(Func):
6757    pass
6758
6759
6760class UnixToStr(Func):
6761    arg_types = {"this": True, "format": False}
6762
6763
6764# https://prestodb.io/docs/current/functions/datetime.html
6765# presto has weird zone/hours/minutes
6766class UnixToTime(Func):
6767    arg_types = {
6768        "this": True,
6769        "scale": False,
6770        "zone": False,
6771        "hours": False,
6772        "minutes": False,
6773        "format": False,
6774    }
6775
6776    SECONDS = Literal.number(0)
6777    DECIS = Literal.number(1)
6778    CENTIS = Literal.number(2)
6779    MILLIS = Literal.number(3)
6780    DECIMILLIS = Literal.number(4)
6781    CENTIMILLIS = Literal.number(5)
6782    MICROS = Literal.number(6)
6783    DECIMICROS = Literal.number(7)
6784    CENTIMICROS = Literal.number(8)
6785    NANOS = Literal.number(9)
6786
6787
6788class UnixToTimeStr(Func):
6789    pass
6790
6791
6792class UnixSeconds(Func):
6793    pass
6794
6795
6796class Uuid(Func):
6797    _sql_names = ["UUID", "GEN_RANDOM_UUID", "GENERATE_UUID", "UUID_STRING"]
6798
6799    arg_types = {"this": False, "name": False}
6800
6801
6802class TimestampFromParts(Func):
6803    _sql_names = ["TIMESTAMP_FROM_PARTS", "TIMESTAMPFROMPARTS"]
6804    arg_types = {
6805        "year": True,
6806        "month": True,
6807        "day": True,
6808        "hour": True,
6809        "min": True,
6810        "sec": True,
6811        "nano": False,
6812        "zone": False,
6813        "milli": False,
6814    }
6815
6816
6817class Upper(Func):
6818    _sql_names = ["UPPER", "UCASE"]
6819
6820
6821class Corr(Binary, AggFunc):
6822    pass
6823
6824
6825class Variance(AggFunc):
6826    _sql_names = ["VARIANCE", "VARIANCE_SAMP", "VAR_SAMP"]
6827
6828
6829class VariancePop(AggFunc):
6830    _sql_names = ["VARIANCE_POP", "VAR_POP"]
6831
6832
6833class CovarSamp(Binary, AggFunc):
6834    pass
6835
6836
6837class CovarPop(Binary, AggFunc):
6838    pass
6839
6840
6841class Week(Func):
6842    arg_types = {"this": True, "mode": False}
6843
6844
6845class XMLElement(Func):
6846    _sql_names = ["XMLELEMENT"]
6847    arg_types = {"this": True, "expressions": False}
6848
6849
6850class XMLTable(Func):
6851    arg_types = {
6852        "this": True,
6853        "namespaces": False,
6854        "passing": False,
6855        "columns": False,
6856        "by_ref": False,
6857    }
6858
6859
6860class XMLNamespace(Expression):
6861    pass
6862
6863
6864class Year(Func):
6865    pass
6866
6867
6868class Use(Expression):
6869    arg_types = {"this": False, "expressions": False, "kind": False}
6870
6871
6872class Merge(DML):
6873    arg_types = {
6874        "this": True,
6875        "using": True,
6876        "on": True,
6877        "whens": True,
6878        "with": False,
6879        "returning": False,
6880    }
6881
6882
6883class When(Expression):
6884    arg_types = {"matched": True, "source": False, "condition": False, "then": True}
6885
6886
6887class Whens(Expression):
6888    """Wraps around one or more WHEN [NOT] MATCHED [...] clauses."""
6889
6890    arg_types = {"expressions": True}
6891
6892
6893# https://docs.oracle.com/javadb/10.8.3.0/ref/rrefsqljnextvaluefor.html
6894# https://learn.microsoft.com/en-us/sql/t-sql/functions/next-value-for-transact-sql?view=sql-server-ver16
6895class NextValueFor(Func):
6896    arg_types = {"this": True, "order": False}
6897
6898
6899# Refers to a trailing semi-colon. This is only used to preserve trailing comments
6900# select 1; -- my comment
6901class Semicolon(Expression):
6902    arg_types = {}
6903
6904
6905def _norm_arg(arg):
6906    return arg.lower() if type(arg) is str else arg
6907
6908
6909ALL_FUNCTIONS = subclasses(__name__, Func, (AggFunc, Anonymous, Func))
6910FUNCTION_BY_NAME = {name: func for func in ALL_FUNCTIONS for name in func.sql_names()}
6911
6912JSON_PATH_PARTS = subclasses(__name__, JSONPathPart, (JSONPathPart,))
6913
6914PERCENTILES = (PercentileCont, PercentileDisc)
6915
6916
6917# Helpers
6918@t.overload
6919def maybe_parse(
6920    sql_or_expression: ExpOrStr,
6921    *,
6922    into: t.Type[E],
6923    dialect: DialectType = None,
6924    prefix: t.Optional[str] = None,
6925    copy: bool = False,
6926    **opts,
6927) -> E: ...
6928
6929
6930@t.overload
6931def maybe_parse(
6932    sql_or_expression: str | E,
6933    *,
6934    into: t.Optional[IntoType] = None,
6935    dialect: DialectType = None,
6936    prefix: t.Optional[str] = None,
6937    copy: bool = False,
6938    **opts,
6939) -> E: ...
6940
6941
6942def maybe_parse(
6943    sql_or_expression: ExpOrStr,
6944    *,
6945    into: t.Optional[IntoType] = None,
6946    dialect: DialectType = None,
6947    prefix: t.Optional[str] = None,
6948    copy: bool = False,
6949    **opts,
6950) -> Expression:
6951    """Gracefully handle a possible string or expression.
6952
6953    Example:
6954        >>> maybe_parse("1")
6955        Literal(this=1, is_string=False)
6956        >>> maybe_parse(to_identifier("x"))
6957        Identifier(this=x, quoted=False)
6958
6959    Args:
6960        sql_or_expression: the SQL code string or an expression
6961        into: the SQLGlot Expression to parse into
6962        dialect: the dialect used to parse the input expressions (in the case that an
6963            input expression is a SQL string).
6964        prefix: a string to prefix the sql with before it gets parsed
6965            (automatically includes a space)
6966        copy: whether to copy the expression.
6967        **opts: other options to use to parse the input expressions (again, in the case
6968            that an input expression is a SQL string).
6969
6970    Returns:
6971        Expression: the parsed or given expression.
6972    """
6973    if isinstance(sql_or_expression, Expression):
6974        if copy:
6975            return sql_or_expression.copy()
6976        return sql_or_expression
6977
6978    if sql_or_expression is None:
6979        raise ParseError("SQL cannot be None")
6980
6981    import sqlglot
6982
6983    sql = str(sql_or_expression)
6984    if prefix:
6985        sql = f"{prefix} {sql}"
6986
6987    return sqlglot.parse_one(sql, read=dialect, into=into, **opts)
6988
6989
6990@t.overload
6991def maybe_copy(instance: None, copy: bool = True) -> None: ...
6992
6993
6994@t.overload
6995def maybe_copy(instance: E, copy: bool = True) -> E: ...
6996
6997
6998def maybe_copy(instance, copy=True):
6999    return instance.copy() if copy and instance else instance
7000
7001
7002def _to_s(node: t.Any, verbose: bool = False, level: int = 0) -> str:
7003    """Generate a textual representation of an Expression tree"""
7004    indent = "\n" + ("  " * (level + 1))
7005    delim = f",{indent}"
7006
7007    if isinstance(node, Expression):
7008        args = {k: v for k, v in node.args.items() if (v is not None and v != []) or verbose}
7009
7010        if (node.type or verbose) and not isinstance(node, DataType):
7011            args["_type"] = node.type
7012        if node.comments or verbose:
7013            args["_comments"] = node.comments
7014
7015        if verbose:
7016            args["_id"] = id(node)
7017
7018        # Inline leaves for a more compact representation
7019        if node.is_leaf():
7020            indent = ""
7021            delim = ", "
7022
7023        items = delim.join([f"{k}={_to_s(v, verbose, level + 1)}" for k, v in args.items()])
7024        return f"{node.__class__.__name__}({indent}{items})"
7025
7026    if isinstance(node, list):
7027        items = delim.join(_to_s(i, verbose, level + 1) for i in node)
7028        items = f"{indent}{items}" if items else ""
7029        return f"[{items}]"
7030
7031    # Indent multiline strings to match the current level
7032    return indent.join(textwrap.dedent(str(node).strip("\n")).splitlines())
7033
7034
7035def _is_wrong_expression(expression, into):
7036    return isinstance(expression, Expression) and not isinstance(expression, into)
7037
7038
7039def _apply_builder(
7040    expression,
7041    instance,
7042    arg,
7043    copy=True,
7044    prefix=None,
7045    into=None,
7046    dialect=None,
7047    into_arg="this",
7048    **opts,
7049):
7050    if _is_wrong_expression(expression, into):
7051        expression = into(**{into_arg: expression})
7052    instance = maybe_copy(instance, copy)
7053    expression = maybe_parse(
7054        sql_or_expression=expression,
7055        prefix=prefix,
7056        into=into,
7057        dialect=dialect,
7058        **opts,
7059    )
7060    instance.set(arg, expression)
7061    return instance
7062
7063
7064def _apply_child_list_builder(
7065    *expressions,
7066    instance,
7067    arg,
7068    append=True,
7069    copy=True,
7070    prefix=None,
7071    into=None,
7072    dialect=None,
7073    properties=None,
7074    **opts,
7075):
7076    instance = maybe_copy(instance, copy)
7077    parsed = []
7078    properties = {} if properties is None else properties
7079
7080    for expression in expressions:
7081        if expression is not None:
7082            if _is_wrong_expression(expression, into):
7083                expression = into(expressions=[expression])
7084
7085            expression = maybe_parse(
7086                expression,
7087                into=into,
7088                dialect=dialect,
7089                prefix=prefix,
7090                **opts,
7091            )
7092            for k, v in expression.args.items():
7093                if k == "expressions":
7094                    parsed.extend(v)
7095                else:
7096                    properties[k] = v
7097
7098    existing = instance.args.get(arg)
7099    if append and existing:
7100        parsed = existing.expressions + parsed
7101
7102    child = into(expressions=parsed)
7103    for k, v in properties.items():
7104        child.set(k, v)
7105    instance.set(arg, child)
7106
7107    return instance
7108
7109
7110def _apply_list_builder(
7111    *expressions,
7112    instance,
7113    arg,
7114    append=True,
7115    copy=True,
7116    prefix=None,
7117    into=None,
7118    dialect=None,
7119    **opts,
7120):
7121    inst = maybe_copy(instance, copy)
7122
7123    expressions = [
7124        maybe_parse(
7125            sql_or_expression=expression,
7126            into=into,
7127            prefix=prefix,
7128            dialect=dialect,
7129            **opts,
7130        )
7131        for expression in expressions
7132        if expression is not None
7133    ]
7134
7135    existing_expressions = inst.args.get(arg)
7136    if append and existing_expressions:
7137        expressions = existing_expressions + expressions
7138
7139    inst.set(arg, expressions)
7140    return inst
7141
7142
7143def _apply_conjunction_builder(
7144    *expressions,
7145    instance,
7146    arg,
7147    into=None,
7148    append=True,
7149    copy=True,
7150    dialect=None,
7151    **opts,
7152):
7153    expressions = [exp for exp in expressions if exp is not None and exp != ""]
7154    if not expressions:
7155        return instance
7156
7157    inst = maybe_copy(instance, copy)
7158
7159    existing = inst.args.get(arg)
7160    if append and existing is not None:
7161        expressions = [existing.this if into else existing] + list(expressions)
7162
7163    node = and_(*expressions, dialect=dialect, copy=copy, **opts)
7164
7165    inst.set(arg, into(this=node) if into else node)
7166    return inst
7167
7168
7169def _apply_cte_builder(
7170    instance: E,
7171    alias: ExpOrStr,
7172    as_: ExpOrStr,
7173    recursive: t.Optional[bool] = None,
7174    materialized: t.Optional[bool] = None,
7175    append: bool = True,
7176    dialect: DialectType = None,
7177    copy: bool = True,
7178    scalar: bool = False,
7179    **opts,
7180) -> E:
7181    alias_expression = maybe_parse(alias, dialect=dialect, into=TableAlias, **opts)
7182    as_expression = maybe_parse(as_, dialect=dialect, copy=copy, **opts)
7183    if scalar and not isinstance(as_expression, Subquery):
7184        # scalar CTE must be wrapped in a subquery
7185        as_expression = Subquery(this=as_expression)
7186    cte = CTE(this=as_expression, alias=alias_expression, materialized=materialized, scalar=scalar)
7187    return _apply_child_list_builder(
7188        cte,
7189        instance=instance,
7190        arg="with",
7191        append=append,
7192        copy=copy,
7193        into=With,
7194        properties={"recursive": recursive or False},
7195    )
7196
7197
7198def _combine(
7199    expressions: t.Sequence[t.Optional[ExpOrStr]],
7200    operator: t.Type[Connector],
7201    dialect: DialectType = None,
7202    copy: bool = True,
7203    wrap: bool = True,
7204    **opts,
7205) -> Expression:
7206    conditions = [
7207        condition(expression, dialect=dialect, copy=copy, **opts)
7208        for expression in expressions
7209        if expression is not None
7210    ]
7211
7212    this, *rest = conditions
7213    if rest and wrap:
7214        this = _wrap(this, Connector)
7215    for expression in rest:
7216        this = operator(this=this, expression=_wrap(expression, Connector) if wrap else expression)
7217
7218    return this
7219
7220
7221@t.overload
7222def _wrap(expression: None, kind: t.Type[Expression]) -> None: ...
7223
7224
7225@t.overload
7226def _wrap(expression: E, kind: t.Type[Expression]) -> E | Paren: ...
7227
7228
7229def _wrap(expression: t.Optional[E], kind: t.Type[Expression]) -> t.Optional[E] | Paren:
7230    return Paren(this=expression) if isinstance(expression, kind) else expression
7231
7232
7233def _apply_set_operation(
7234    *expressions: ExpOrStr,
7235    set_operation: t.Type[S],
7236    distinct: bool = True,
7237    dialect: DialectType = None,
7238    copy: bool = True,
7239    **opts,
7240) -> S:
7241    return reduce(
7242        lambda x, y: set_operation(this=x, expression=y, distinct=distinct),
7243        (maybe_parse(e, dialect=dialect, copy=copy, **opts) for e in expressions),
7244    )
7245
7246
7247def union(
7248    *expressions: ExpOrStr,
7249    distinct: bool = True,
7250    dialect: DialectType = None,
7251    copy: bool = True,
7252    **opts,
7253) -> Union:
7254    """
7255    Initializes a syntax tree for the `UNION` operation.
7256
7257    Example:
7258        >>> union("SELECT * FROM foo", "SELECT * FROM bla").sql()
7259        'SELECT * FROM foo UNION SELECT * FROM bla'
7260
7261    Args:
7262        expressions: the SQL code strings, corresponding to the `UNION`'s operands.
7263            If `Expression` instances are passed, they will be used as-is.
7264        distinct: set the DISTINCT flag if and only if this is true.
7265        dialect: the dialect used to parse the input expression.
7266        copy: whether to copy the expression.
7267        opts: other options to use to parse the input expressions.
7268
7269    Returns:
7270        The new Union instance.
7271    """
7272    assert len(expressions) >= 2, "At least two expressions are required by `union`."
7273    return _apply_set_operation(
7274        *expressions, set_operation=Union, distinct=distinct, dialect=dialect, copy=copy, **opts
7275    )
7276
7277
7278def intersect(
7279    *expressions: ExpOrStr,
7280    distinct: bool = True,
7281    dialect: DialectType = None,
7282    copy: bool = True,
7283    **opts,
7284) -> Intersect:
7285    """
7286    Initializes a syntax tree for the `INTERSECT` operation.
7287
7288    Example:
7289        >>> intersect("SELECT * FROM foo", "SELECT * FROM bla").sql()
7290        'SELECT * FROM foo INTERSECT SELECT * FROM bla'
7291
7292    Args:
7293        expressions: the SQL code strings, corresponding to the `INTERSECT`'s operands.
7294            If `Expression` instances are passed, they will be used as-is.
7295        distinct: set the DISTINCT flag if and only if this is true.
7296        dialect: the dialect used to parse the input expression.
7297        copy: whether to copy the expression.
7298        opts: other options to use to parse the input expressions.
7299
7300    Returns:
7301        The new Intersect instance.
7302    """
7303    assert len(expressions) >= 2, "At least two expressions are required by `intersect`."
7304    return _apply_set_operation(
7305        *expressions, set_operation=Intersect, distinct=distinct, dialect=dialect, copy=copy, **opts
7306    )
7307
7308
7309def except_(
7310    *expressions: ExpOrStr,
7311    distinct: bool = True,
7312    dialect: DialectType = None,
7313    copy: bool = True,
7314    **opts,
7315) -> Except:
7316    """
7317    Initializes a syntax tree for the `EXCEPT` operation.
7318
7319    Example:
7320        >>> except_("SELECT * FROM foo", "SELECT * FROM bla").sql()
7321        'SELECT * FROM foo EXCEPT SELECT * FROM bla'
7322
7323    Args:
7324        expressions: the SQL code strings, corresponding to the `EXCEPT`'s operands.
7325            If `Expression` instances are passed, they will be used as-is.
7326        distinct: set the DISTINCT flag if and only if this is true.
7327        dialect: the dialect used to parse the input expression.
7328        copy: whether to copy the expression.
7329        opts: other options to use to parse the input expressions.
7330
7331    Returns:
7332        The new Except instance.
7333    """
7334    assert len(expressions) >= 2, "At least two expressions are required by `except_`."
7335    return _apply_set_operation(
7336        *expressions, set_operation=Except, distinct=distinct, dialect=dialect, copy=copy, **opts
7337    )
7338
7339
7340def select(*expressions: ExpOrStr, dialect: DialectType = None, **opts) -> Select:
7341    """
7342    Initializes a syntax tree from one or multiple SELECT expressions.
7343
7344    Example:
7345        >>> select("col1", "col2").from_("tbl").sql()
7346        'SELECT col1, col2 FROM tbl'
7347
7348    Args:
7349        *expressions: the SQL code string to parse as the expressions of a
7350            SELECT statement. If an Expression instance is passed, this is used as-is.
7351        dialect: the dialect used to parse the input expressions (in the case that an
7352            input expression is a SQL string).
7353        **opts: other options to use to parse the input expressions (again, in the case
7354            that an input expression is a SQL string).
7355
7356    Returns:
7357        Select: the syntax tree for the SELECT statement.
7358    """
7359    return Select().select(*expressions, dialect=dialect, **opts)
7360
7361
7362def from_(expression: ExpOrStr, dialect: DialectType = None, **opts) -> Select:
7363    """
7364    Initializes a syntax tree from a FROM expression.
7365
7366    Example:
7367        >>> from_("tbl").select("col1", "col2").sql()
7368        'SELECT col1, col2 FROM tbl'
7369
7370    Args:
7371        *expression: the SQL code string to parse as the FROM expressions of a
7372            SELECT statement. If an Expression instance is passed, this is used as-is.
7373        dialect: the dialect used to parse the input expression (in the case that the
7374            input expression is a SQL string).
7375        **opts: other options to use to parse the input expressions (again, in the case
7376            that the input expression is a SQL string).
7377
7378    Returns:
7379        Select: the syntax tree for the SELECT statement.
7380    """
7381    return Select().from_(expression, dialect=dialect, **opts)
7382
7383
7384def update(
7385    table: str | Table,
7386    properties: t.Optional[dict] = None,
7387    where: t.Optional[ExpOrStr] = None,
7388    from_: t.Optional[ExpOrStr] = None,
7389    with_: t.Optional[t.Dict[str, ExpOrStr]] = None,
7390    dialect: DialectType = None,
7391    **opts,
7392) -> Update:
7393    """
7394    Creates an update statement.
7395
7396    Example:
7397        >>> update("my_table", {"x": 1, "y": "2", "z": None}, from_="baz_cte", where="baz_cte.id > 1 and my_table.id = baz_cte.id", with_={"baz_cte": "SELECT id FROM foo"}).sql()
7398        "WITH baz_cte AS (SELECT id FROM foo) UPDATE my_table SET x = 1, y = '2', z = NULL FROM baz_cte WHERE baz_cte.id > 1 AND my_table.id = baz_cte.id"
7399
7400    Args:
7401        properties: dictionary of properties to SET which are
7402            auto converted to sql objects eg None -> NULL
7403        where: sql conditional parsed into a WHERE statement
7404        from_: sql statement parsed into a FROM statement
7405        with_: dictionary of CTE aliases / select statements to include in a WITH clause.
7406        dialect: the dialect used to parse the input expressions.
7407        **opts: other options to use to parse the input expressions.
7408
7409    Returns:
7410        Update: the syntax tree for the UPDATE statement.
7411    """
7412    update_expr = Update(this=maybe_parse(table, into=Table, dialect=dialect))
7413    if properties:
7414        update_expr.set(
7415            "expressions",
7416            [
7417                EQ(this=maybe_parse(k, dialect=dialect, **opts), expression=convert(v))
7418                for k, v in properties.items()
7419            ],
7420        )
7421    if from_:
7422        update_expr.set(
7423            "from",
7424            maybe_parse(from_, into=From, dialect=dialect, prefix="FROM", **opts),
7425        )
7426    if isinstance(where, Condition):
7427        where = Where(this=where)
7428    if where:
7429        update_expr.set(
7430            "where",
7431            maybe_parse(where, into=Where, dialect=dialect, prefix="WHERE", **opts),
7432        )
7433    if with_:
7434        cte_list = [
7435            alias_(CTE(this=maybe_parse(qry, dialect=dialect, **opts)), alias, table=True)
7436            for alias, qry in with_.items()
7437        ]
7438        update_expr.set(
7439            "with",
7440            With(expressions=cte_list),
7441        )
7442    return update_expr
7443
7444
7445def delete(
7446    table: ExpOrStr,
7447    where: t.Optional[ExpOrStr] = None,
7448    returning: t.Optional[ExpOrStr] = None,
7449    dialect: DialectType = None,
7450    **opts,
7451) -> Delete:
7452    """
7453    Builds a delete statement.
7454
7455    Example:
7456        >>> delete("my_table", where="id > 1").sql()
7457        'DELETE FROM my_table WHERE id > 1'
7458
7459    Args:
7460        where: sql conditional parsed into a WHERE statement
7461        returning: sql conditional parsed into a RETURNING statement
7462        dialect: the dialect used to parse the input expressions.
7463        **opts: other options to use to parse the input expressions.
7464
7465    Returns:
7466        Delete: the syntax tree for the DELETE statement.
7467    """
7468    delete_expr = Delete().delete(table, dialect=dialect, copy=False, **opts)
7469    if where:
7470        delete_expr = delete_expr.where(where, dialect=dialect, copy=False, **opts)
7471    if returning:
7472        delete_expr = delete_expr.returning(returning, dialect=dialect, copy=False, **opts)
7473    return delete_expr
7474
7475
7476def insert(
7477    expression: ExpOrStr,
7478    into: ExpOrStr,
7479    columns: t.Optional[t.Sequence[str | Identifier]] = None,
7480    overwrite: t.Optional[bool] = None,
7481    returning: t.Optional[ExpOrStr] = None,
7482    dialect: DialectType = None,
7483    copy: bool = True,
7484    **opts,
7485) -> Insert:
7486    """
7487    Builds an INSERT statement.
7488
7489    Example:
7490        >>> insert("VALUES (1, 2, 3)", "tbl").sql()
7491        'INSERT INTO tbl VALUES (1, 2, 3)'
7492
7493    Args:
7494        expression: the sql string or expression of the INSERT statement
7495        into: the tbl to insert data to.
7496        columns: optionally the table's column names.
7497        overwrite: whether to INSERT OVERWRITE or not.
7498        returning: sql conditional parsed into a RETURNING statement
7499        dialect: the dialect used to parse the input expressions.
7500        copy: whether to copy the expression.
7501        **opts: other options to use to parse the input expressions.
7502
7503    Returns:
7504        Insert: the syntax tree for the INSERT statement.
7505    """
7506    expr = maybe_parse(expression, dialect=dialect, copy=copy, **opts)
7507    this: Table | Schema = maybe_parse(into, into=Table, dialect=dialect, copy=copy, **opts)
7508
7509    if columns:
7510        this = Schema(this=this, expressions=[to_identifier(c, copy=copy) for c in columns])
7511
7512    insert = Insert(this=this, expression=expr, overwrite=overwrite)
7513
7514    if returning:
7515        insert = insert.returning(returning, dialect=dialect, copy=False, **opts)
7516
7517    return insert
7518
7519
7520def merge(
7521    *when_exprs: ExpOrStr,
7522    into: ExpOrStr,
7523    using: ExpOrStr,
7524    on: ExpOrStr,
7525    returning: t.Optional[ExpOrStr] = None,
7526    dialect: DialectType = None,
7527    copy: bool = True,
7528    **opts,
7529) -> Merge:
7530    """
7531    Builds a MERGE statement.
7532
7533    Example:
7534        >>> merge("WHEN MATCHED THEN UPDATE SET col1 = source_table.col1",
7535        ...       "WHEN NOT MATCHED THEN INSERT (col1) VALUES (source_table.col1)",
7536        ...       into="my_table",
7537        ...       using="source_table",
7538        ...       on="my_table.id = source_table.id").sql()
7539        'MERGE INTO my_table USING source_table ON my_table.id = source_table.id WHEN MATCHED THEN UPDATE SET col1 = source_table.col1 WHEN NOT MATCHED THEN INSERT (col1) VALUES (source_table.col1)'
7540
7541    Args:
7542        *when_exprs: The WHEN clauses specifying actions for matched and unmatched rows.
7543        into: The target table to merge data into.
7544        using: The source table to merge data from.
7545        on: The join condition for the merge.
7546        returning: The columns to return from the merge.
7547        dialect: The dialect used to parse the input expressions.
7548        copy: Whether to copy the expression.
7549        **opts: Other options to use to parse the input expressions.
7550
7551    Returns:
7552        Merge: The syntax tree for the MERGE statement.
7553    """
7554    expressions: t.List[Expression] = []
7555    for when_expr in when_exprs:
7556        expression = maybe_parse(when_expr, dialect=dialect, copy=copy, into=Whens, **opts)
7557        expressions.extend([expression] if isinstance(expression, When) else expression.expressions)
7558
7559    merge = Merge(
7560        this=maybe_parse(into, dialect=dialect, copy=copy, **opts),
7561        using=maybe_parse(using, dialect=dialect, copy=copy, **opts),
7562        on=maybe_parse(on, dialect=dialect, copy=copy, **opts),
7563        whens=Whens(expressions=expressions),
7564    )
7565    if returning:
7566        merge = merge.returning(returning, dialect=dialect, copy=False, **opts)
7567
7568    return merge
7569
7570
7571def condition(
7572    expression: ExpOrStr, dialect: DialectType = None, copy: bool = True, **opts
7573) -> Condition:
7574    """
7575    Initialize a logical condition expression.
7576
7577    Example:
7578        >>> condition("x=1").sql()
7579        'x = 1'
7580
7581        This is helpful for composing larger logical syntax trees:
7582        >>> where = condition("x=1")
7583        >>> where = where.and_("y=1")
7584        >>> Select().from_("tbl").select("*").where(where).sql()
7585        'SELECT * FROM tbl WHERE x = 1 AND y = 1'
7586
7587    Args:
7588        *expression: the SQL code string to parse.
7589            If an Expression instance is passed, this is used as-is.
7590        dialect: the dialect used to parse the input expression (in the case that the
7591            input expression is a SQL string).
7592        copy: Whether to copy `expression` (only applies to expressions).
7593        **opts: other options to use to parse the input expressions (again, in the case
7594            that the input expression is a SQL string).
7595
7596    Returns:
7597        The new Condition instance
7598    """
7599    return maybe_parse(
7600        expression,
7601        into=Condition,
7602        dialect=dialect,
7603        copy=copy,
7604        **opts,
7605    )
7606
7607
7608def and_(
7609    *expressions: t.Optional[ExpOrStr],
7610    dialect: DialectType = None,
7611    copy: bool = True,
7612    wrap: bool = True,
7613    **opts,
7614) -> Condition:
7615    """
7616    Combine multiple conditions with an AND logical operator.
7617
7618    Example:
7619        >>> and_("x=1", and_("y=1", "z=1")).sql()
7620        'x = 1 AND (y = 1 AND z = 1)'
7621
7622    Args:
7623        *expressions: the SQL code strings to parse.
7624            If an Expression instance is passed, this is used as-is.
7625        dialect: the dialect used to parse the input expression.
7626        copy: whether to copy `expressions` (only applies to Expressions).
7627        wrap: whether to wrap the operands in `Paren`s. This is true by default to avoid
7628            precedence issues, but can be turned off when the produced AST is too deep and
7629            causes recursion-related issues.
7630        **opts: other options to use to parse the input expressions.
7631
7632    Returns:
7633        The new condition
7634    """
7635    return t.cast(Condition, _combine(expressions, And, dialect, copy=copy, wrap=wrap, **opts))
7636
7637
7638def or_(
7639    *expressions: t.Optional[ExpOrStr],
7640    dialect: DialectType = None,
7641    copy: bool = True,
7642    wrap: bool = True,
7643    **opts,
7644) -> Condition:
7645    """
7646    Combine multiple conditions with an OR logical operator.
7647
7648    Example:
7649        >>> or_("x=1", or_("y=1", "z=1")).sql()
7650        'x = 1 OR (y = 1 OR z = 1)'
7651
7652    Args:
7653        *expressions: the SQL code strings to parse.
7654            If an Expression instance is passed, this is used as-is.
7655        dialect: the dialect used to parse the input expression.
7656        copy: whether to copy `expressions` (only applies to Expressions).
7657        wrap: whether to wrap the operands in `Paren`s. This is true by default to avoid
7658            precedence issues, but can be turned off when the produced AST is too deep and
7659            causes recursion-related issues.
7660        **opts: other options to use to parse the input expressions.
7661
7662    Returns:
7663        The new condition
7664    """
7665    return t.cast(Condition, _combine(expressions, Or, dialect, copy=copy, wrap=wrap, **opts))
7666
7667
7668def xor(
7669    *expressions: t.Optional[ExpOrStr],
7670    dialect: DialectType = None,
7671    copy: bool = True,
7672    wrap: bool = True,
7673    **opts,
7674) -> Condition:
7675    """
7676    Combine multiple conditions with an XOR logical operator.
7677
7678    Example:
7679        >>> xor("x=1", xor("y=1", "z=1")).sql()
7680        'x = 1 XOR (y = 1 XOR z = 1)'
7681
7682    Args:
7683        *expressions: the SQL code strings to parse.
7684            If an Expression instance is passed, this is used as-is.
7685        dialect: the dialect used to parse the input expression.
7686        copy: whether to copy `expressions` (only applies to Expressions).
7687        wrap: whether to wrap the operands in `Paren`s. This is true by default to avoid
7688            precedence issues, but can be turned off when the produced AST is too deep and
7689            causes recursion-related issues.
7690        **opts: other options to use to parse the input expressions.
7691
7692    Returns:
7693        The new condition
7694    """
7695    return t.cast(Condition, _combine(expressions, Xor, dialect, copy=copy, wrap=wrap, **opts))
7696
7697
7698def not_(expression: ExpOrStr, dialect: DialectType = None, copy: bool = True, **opts) -> Not:
7699    """
7700    Wrap a condition with a NOT operator.
7701
7702    Example:
7703        >>> not_("this_suit='black'").sql()
7704        "NOT this_suit = 'black'"
7705
7706    Args:
7707        expression: the SQL code string to parse.
7708            If an Expression instance is passed, this is used as-is.
7709        dialect: the dialect used to parse the input expression.
7710        copy: whether to copy the expression or not.
7711        **opts: other options to use to parse the input expressions.
7712
7713    Returns:
7714        The new condition.
7715    """
7716    this = condition(
7717        expression,
7718        dialect=dialect,
7719        copy=copy,
7720        **opts,
7721    )
7722    return Not(this=_wrap(this, Connector))
7723
7724
7725def paren(expression: ExpOrStr, copy: bool = True) -> Paren:
7726    """
7727    Wrap an expression in parentheses.
7728
7729    Example:
7730        >>> paren("5 + 3").sql()
7731        '(5 + 3)'
7732
7733    Args:
7734        expression: the SQL code string to parse.
7735            If an Expression instance is passed, this is used as-is.
7736        copy: whether to copy the expression or not.
7737
7738    Returns:
7739        The wrapped expression.
7740    """
7741    return Paren(this=maybe_parse(expression, copy=copy))
7742
7743
7744SAFE_IDENTIFIER_RE: t.Pattern[str] = re.compile(r"^[_a-zA-Z][\w]*$")
7745
7746
7747@t.overload
7748def to_identifier(name: None, quoted: t.Optional[bool] = None, copy: bool = True) -> None: ...
7749
7750
7751@t.overload
7752def to_identifier(
7753    name: str | Identifier, quoted: t.Optional[bool] = None, copy: bool = True
7754) -> Identifier: ...
7755
7756
7757def to_identifier(name, quoted=None, copy=True):
7758    """Builds an identifier.
7759
7760    Args:
7761        name: The name to turn into an identifier.
7762        quoted: Whether to force quote the identifier.
7763        copy: Whether to copy name if it's an Identifier.
7764
7765    Returns:
7766        The identifier ast node.
7767    """
7768
7769    if name is None:
7770        return None
7771
7772    if isinstance(name, Identifier):
7773        identifier = maybe_copy(name, copy)
7774    elif isinstance(name, str):
7775        identifier = Identifier(
7776            this=name,
7777            quoted=not SAFE_IDENTIFIER_RE.match(name) if quoted is None else quoted,
7778        )
7779    else:
7780        raise ValueError(f"Name needs to be a string or an Identifier, got: {name.__class__}")
7781    return identifier
7782
7783
7784def parse_identifier(name: str | Identifier, dialect: DialectType = None) -> Identifier:
7785    """
7786    Parses a given string into an identifier.
7787
7788    Args:
7789        name: The name to parse into an identifier.
7790        dialect: The dialect to parse against.
7791
7792    Returns:
7793        The identifier ast node.
7794    """
7795    try:
7796        expression = maybe_parse(name, dialect=dialect, into=Identifier)
7797    except (ParseError, TokenError):
7798        expression = to_identifier(name)
7799
7800    return expression
7801
7802
7803INTERVAL_STRING_RE = re.compile(r"\s*([0-9]+)\s*([a-zA-Z]+)\s*")
7804
7805
7806def to_interval(interval: str | Literal) -> Interval:
7807    """Builds an interval expression from a string like '1 day' or '5 months'."""
7808    if isinstance(interval, Literal):
7809        if not interval.is_string:
7810            raise ValueError("Invalid interval string.")
7811
7812        interval = interval.this
7813
7814    interval = maybe_parse(f"INTERVAL {interval}")
7815    assert isinstance(interval, Interval)
7816    return interval
7817
7818
7819def to_table(
7820    sql_path: str | Table, dialect: DialectType = None, copy: bool = True, **kwargs
7821) -> Table:
7822    """
7823    Create a table expression from a `[catalog].[schema].[table]` sql path. Catalog and schema are optional.
7824    If a table is passed in then that table is returned.
7825
7826    Args:
7827        sql_path: a `[catalog].[schema].[table]` string.
7828        dialect: the source dialect according to which the table name will be parsed.
7829        copy: Whether to copy a table if it is passed in.
7830        kwargs: the kwargs to instantiate the resulting `Table` expression with.
7831
7832    Returns:
7833        A table expression.
7834    """
7835    if isinstance(sql_path, Table):
7836        return maybe_copy(sql_path, copy=copy)
7837
7838    table = maybe_parse(sql_path, into=Table, dialect=dialect)
7839
7840    for k, v in kwargs.items():
7841        table.set(k, v)
7842
7843    return table
7844
7845
7846def to_column(
7847    sql_path: str | Column,
7848    quoted: t.Optional[bool] = None,
7849    dialect: DialectType = None,
7850    copy: bool = True,
7851    **kwargs,
7852) -> Column:
7853    """
7854    Create a column from a `[table].[column]` sql path. Table is optional.
7855    If a column is passed in then that column is returned.
7856
7857    Args:
7858        sql_path: a `[table].[column]` string.
7859        quoted: Whether or not to force quote identifiers.
7860        dialect: the source dialect according to which the column name will be parsed.
7861        copy: Whether to copy a column if it is passed in.
7862        kwargs: the kwargs to instantiate the resulting `Column` expression with.
7863
7864    Returns:
7865        A column expression.
7866    """
7867    if isinstance(sql_path, Column):
7868        return maybe_copy(sql_path, copy=copy)
7869
7870    try:
7871        col = maybe_parse(sql_path, into=Column, dialect=dialect)
7872    except ParseError:
7873        return column(*reversed(sql_path.split(".")), quoted=quoted, **kwargs)
7874
7875    for k, v in kwargs.items():
7876        col.set(k, v)
7877
7878    if quoted:
7879        for i in col.find_all(Identifier):
7880            i.set("quoted", True)
7881
7882    return col
7883
7884
7885def alias_(
7886    expression: ExpOrStr,
7887    alias: t.Optional[str | Identifier],
7888    table: bool | t.Sequence[str | Identifier] = False,
7889    quoted: t.Optional[bool] = None,
7890    dialect: DialectType = None,
7891    copy: bool = True,
7892    **opts,
7893):
7894    """Create an Alias expression.
7895
7896    Example:
7897        >>> alias_('foo', 'bar').sql()
7898        'foo AS bar'
7899
7900        >>> alias_('(select 1, 2)', 'bar', table=['a', 'b']).sql()
7901        '(SELECT 1, 2) AS bar(a, b)'
7902
7903    Args:
7904        expression: the SQL code strings to parse.
7905            If an Expression instance is passed, this is used as-is.
7906        alias: the alias name to use. If the name has
7907            special characters it is quoted.
7908        table: Whether to create a table alias, can also be a list of columns.
7909        quoted: whether to quote the alias
7910        dialect: the dialect used to parse the input expression.
7911        copy: Whether to copy the expression.
7912        **opts: other options to use to parse the input expressions.
7913
7914    Returns:
7915        Alias: the aliased expression
7916    """
7917    exp = maybe_parse(expression, dialect=dialect, copy=copy, **opts)
7918    alias = to_identifier(alias, quoted=quoted)
7919
7920    if table:
7921        table_alias = TableAlias(this=alias)
7922        exp.set("alias", table_alias)
7923
7924        if not isinstance(table, bool):
7925            for column in table:
7926                table_alias.append("columns", to_identifier(column, quoted=quoted))
7927
7928        return exp
7929
7930    # We don't set the "alias" arg for Window expressions, because that would add an IDENTIFIER node in
7931    # the AST, representing a "named_window" [1] construct (eg. bigquery). What we want is an ALIAS node
7932    # for the complete Window expression.
7933    #
7934    # [1]: https://cloud.google.com/bigquery/docs/reference/standard-sql/window-function-calls
7935
7936    if "alias" in exp.arg_types and not isinstance(exp, Window):
7937        exp.set("alias", alias)
7938        return exp
7939    return Alias(this=exp, alias=alias)
7940
7941
7942def subquery(
7943    expression: ExpOrStr,
7944    alias: t.Optional[Identifier | str] = None,
7945    dialect: DialectType = None,
7946    **opts,
7947) -> Select:
7948    """
7949    Build a subquery expression that's selected from.
7950
7951    Example:
7952        >>> subquery('select x from tbl', 'bar').select('x').sql()
7953        'SELECT x FROM (SELECT x FROM tbl) AS bar'
7954
7955    Args:
7956        expression: the SQL code strings to parse.
7957            If an Expression instance is passed, this is used as-is.
7958        alias: the alias name to use.
7959        dialect: the dialect used to parse the input expression.
7960        **opts: other options to use to parse the input expressions.
7961
7962    Returns:
7963        A new Select instance with the subquery expression included.
7964    """
7965
7966    expression = maybe_parse(expression, dialect=dialect, **opts).subquery(alias, **opts)
7967    return Select().from_(expression, dialect=dialect, **opts)
7968
7969
7970@t.overload
7971def column(
7972    col: str | Identifier,
7973    table: t.Optional[str | Identifier] = None,
7974    db: t.Optional[str | Identifier] = None,
7975    catalog: t.Optional[str | Identifier] = None,
7976    *,
7977    fields: t.Collection[t.Union[str, Identifier]],
7978    quoted: t.Optional[bool] = None,
7979    copy: bool = True,
7980) -> Dot:
7981    pass
7982
7983
7984@t.overload
7985def column(
7986    col: str | Identifier,
7987    table: t.Optional[str | Identifier] = None,
7988    db: t.Optional[str | Identifier] = None,
7989    catalog: t.Optional[str | Identifier] = None,
7990    *,
7991    fields: Lit[None] = None,
7992    quoted: t.Optional[bool] = None,
7993    copy: bool = True,
7994) -> Column:
7995    pass
7996
7997
7998def column(
7999    col,
8000    table=None,
8001    db=None,
8002    catalog=None,
8003    *,
8004    fields=None,
8005    quoted=None,
8006    copy=True,
8007):
8008    """
8009    Build a Column.
8010
8011    Args:
8012        col: Column name.
8013        table: Table name.
8014        db: Database name.
8015        catalog: Catalog name.
8016        fields: Additional fields using dots.
8017        quoted: Whether to force quotes on the column's identifiers.
8018        copy: Whether to copy identifiers if passed in.
8019
8020    Returns:
8021        The new Column instance.
8022    """
8023    this = Column(
8024        this=to_identifier(col, quoted=quoted, copy=copy),
8025        table=to_identifier(table, quoted=quoted, copy=copy),
8026        db=to_identifier(db, quoted=quoted, copy=copy),
8027        catalog=to_identifier(catalog, quoted=quoted, copy=copy),
8028    )
8029
8030    if fields:
8031        this = Dot.build(
8032            (this, *(to_identifier(field, quoted=quoted, copy=copy) for field in fields))
8033        )
8034    return this
8035
8036
8037def cast(
8038    expression: ExpOrStr, to: DATA_TYPE, copy: bool = True, dialect: DialectType = None, **opts
8039) -> Cast:
8040    """Cast an expression to a data type.
8041
8042    Example:
8043        >>> cast('x + 1', 'int').sql()
8044        'CAST(x + 1 AS INT)'
8045
8046    Args:
8047        expression: The expression to cast.
8048        to: The datatype to cast to.
8049        copy: Whether to copy the supplied expressions.
8050        dialect: The target dialect. This is used to prevent a re-cast in the following scenario:
8051            - The expression to be cast is already a exp.Cast expression
8052            - The existing cast is to a type that is logically equivalent to new type
8053
8054            For example, if :expression='CAST(x as DATETIME)' and :to=Type.TIMESTAMP,
8055            but in the target dialect DATETIME is mapped to TIMESTAMP, then we will NOT return `CAST(x (as DATETIME) as TIMESTAMP)`
8056            and instead just return the original expression `CAST(x as DATETIME)`.
8057
8058            This is to prevent it being output as a double cast `CAST(x (as TIMESTAMP) as TIMESTAMP)` once the DATETIME -> TIMESTAMP
8059            mapping is applied in the target dialect generator.
8060
8061    Returns:
8062        The new Cast instance.
8063    """
8064    expr = maybe_parse(expression, copy=copy, dialect=dialect, **opts)
8065    data_type = DataType.build(to, copy=copy, dialect=dialect, **opts)
8066
8067    # dont re-cast if the expression is already a cast to the correct type
8068    if isinstance(expr, Cast):
8069        from sqlglot.dialects.dialect import Dialect
8070
8071        target_dialect = Dialect.get_or_raise(dialect)
8072        type_mapping = target_dialect.generator_class.TYPE_MAPPING
8073
8074        existing_cast_type: DataType.Type = expr.to.this
8075        new_cast_type: DataType.Type = data_type.this
8076        types_are_equivalent = type_mapping.get(
8077            existing_cast_type, existing_cast_type.value
8078        ) == type_mapping.get(new_cast_type, new_cast_type.value)
8079
8080        if expr.is_type(data_type) or types_are_equivalent:
8081            return expr
8082
8083    expr = Cast(this=expr, to=data_type)
8084    expr.type = data_type
8085
8086    return expr
8087
8088
8089def table_(
8090    table: Identifier | str,
8091    db: t.Optional[Identifier | str] = None,
8092    catalog: t.Optional[Identifier | str] = None,
8093    quoted: t.Optional[bool] = None,
8094    alias: t.Optional[Identifier | str] = None,
8095) -> Table:
8096    """Build a Table.
8097
8098    Args:
8099        table: Table name.
8100        db: Database name.
8101        catalog: Catalog name.
8102        quote: Whether to force quotes on the table's identifiers.
8103        alias: Table's alias.
8104
8105    Returns:
8106        The new Table instance.
8107    """
8108    return Table(
8109        this=to_identifier(table, quoted=quoted) if table else None,
8110        db=to_identifier(db, quoted=quoted) if db else None,
8111        catalog=to_identifier(catalog, quoted=quoted) if catalog else None,
8112        alias=TableAlias(this=to_identifier(alias)) if alias else None,
8113    )
8114
8115
8116def values(
8117    values: t.Iterable[t.Tuple[t.Any, ...]],
8118    alias: t.Optional[str] = None,
8119    columns: t.Optional[t.Iterable[str] | t.Dict[str, DataType]] = None,
8120) -> Values:
8121    """Build VALUES statement.
8122
8123    Example:
8124        >>> values([(1, '2')]).sql()
8125        "VALUES (1, '2')"
8126
8127    Args:
8128        values: values statements that will be converted to SQL
8129        alias: optional alias
8130        columns: Optional list of ordered column names or ordered dictionary of column names to types.
8131         If either are provided then an alias is also required.
8132
8133    Returns:
8134        Values: the Values expression object
8135    """
8136    if columns and not alias:
8137        raise ValueError("Alias is required when providing columns")
8138
8139    return Values(
8140        expressions=[convert(tup) for tup in values],
8141        alias=(
8142            TableAlias(this=to_identifier(alias), columns=[to_identifier(x) for x in columns])
8143            if columns
8144            else (TableAlias(this=to_identifier(alias)) if alias else None)
8145        ),
8146    )
8147
8148
8149def var(name: t.Optional[ExpOrStr]) -> Var:
8150    """Build a SQL variable.
8151
8152    Example:
8153        >>> repr(var('x'))
8154        'Var(this=x)'
8155
8156        >>> repr(var(column('x', table='y')))
8157        'Var(this=x)'
8158
8159    Args:
8160        name: The name of the var or an expression who's name will become the var.
8161
8162    Returns:
8163        The new variable node.
8164    """
8165    if not name:
8166        raise ValueError("Cannot convert empty name into var.")
8167
8168    if isinstance(name, Expression):
8169        name = name.name
8170    return Var(this=name)
8171
8172
8173def rename_table(
8174    old_name: str | Table,
8175    new_name: str | Table,
8176    dialect: DialectType = None,
8177) -> Alter:
8178    """Build ALTER TABLE... RENAME... expression
8179
8180    Args:
8181        old_name: The old name of the table
8182        new_name: The new name of the table
8183        dialect: The dialect to parse the table.
8184
8185    Returns:
8186        Alter table expression
8187    """
8188    old_table = to_table(old_name, dialect=dialect)
8189    new_table = to_table(new_name, dialect=dialect)
8190    return Alter(
8191        this=old_table,
8192        kind="TABLE",
8193        actions=[
8194            AlterRename(this=new_table),
8195        ],
8196    )
8197
8198
8199def rename_column(
8200    table_name: str | Table,
8201    old_column_name: str | Column,
8202    new_column_name: str | Column,
8203    exists: t.Optional[bool] = None,
8204    dialect: DialectType = None,
8205) -> Alter:
8206    """Build ALTER TABLE... RENAME COLUMN... expression
8207
8208    Args:
8209        table_name: Name of the table
8210        old_column: The old name of the column
8211        new_column: The new name of the column
8212        exists: Whether to add the `IF EXISTS` clause
8213        dialect: The dialect to parse the table/column.
8214
8215    Returns:
8216        Alter table expression
8217    """
8218    table = to_table(table_name, dialect=dialect)
8219    old_column = to_column(old_column_name, dialect=dialect)
8220    new_column = to_column(new_column_name, dialect=dialect)
8221    return Alter(
8222        this=table,
8223        kind="TABLE",
8224        actions=[
8225            RenameColumn(this=old_column, to=new_column, exists=exists),
8226        ],
8227    )
8228
8229
8230def convert(value: t.Any, copy: bool = False) -> Expression:
8231    """Convert a python value into an expression object.
8232
8233    Raises an error if a conversion is not possible.
8234
8235    Args:
8236        value: A python object.
8237        copy: Whether to copy `value` (only applies to Expressions and collections).
8238
8239    Returns:
8240        The equivalent expression object.
8241    """
8242    if isinstance(value, Expression):
8243        return maybe_copy(value, copy)
8244    if isinstance(value, str):
8245        return Literal.string(value)
8246    if isinstance(value, bool):
8247        return Boolean(this=value)
8248    if value is None or (isinstance(value, float) and math.isnan(value)):
8249        return null()
8250    if isinstance(value, numbers.Number):
8251        return Literal.number(value)
8252    if isinstance(value, bytes):
8253        return HexString(this=value.hex())
8254    if isinstance(value, datetime.datetime):
8255        datetime_literal = Literal.string(value.isoformat(sep=" "))
8256
8257        tz = None
8258        if value.tzinfo:
8259            # this works for zoneinfo.ZoneInfo, pytz.timezone and datetime.datetime.utc to return IANA timezone names like "America/Los_Angeles"
8260            # instead of abbreviations like "PDT". This is for consistency with other timezone handling functions in SQLGlot
8261            tz = Literal.string(str(value.tzinfo))
8262
8263        return TimeStrToTime(this=datetime_literal, zone=tz)
8264    if isinstance(value, datetime.date):
8265        date_literal = Literal.string(value.strftime("%Y-%m-%d"))
8266        return DateStrToDate(this=date_literal)
8267    if isinstance(value, tuple):
8268        if hasattr(value, "_fields"):
8269            return Struct(
8270                expressions=[
8271                    PropertyEQ(
8272                        this=to_identifier(k), expression=convert(getattr(value, k), copy=copy)
8273                    )
8274                    for k in value._fields
8275                ]
8276            )
8277        return Tuple(expressions=[convert(v, copy=copy) for v in value])
8278    if isinstance(value, list):
8279        return Array(expressions=[convert(v, copy=copy) for v in value])
8280    if isinstance(value, dict):
8281        return Map(
8282            keys=Array(expressions=[convert(k, copy=copy) for k in value]),
8283            values=Array(expressions=[convert(v, copy=copy) for v in value.values()]),
8284        )
8285    if hasattr(value, "__dict__"):
8286        return Struct(
8287            expressions=[
8288                PropertyEQ(this=to_identifier(k), expression=convert(v, copy=copy))
8289                for k, v in value.__dict__.items()
8290            ]
8291        )
8292    raise ValueError(f"Cannot convert {value}")
8293
8294
8295def replace_children(expression: Expression, fun: t.Callable, *args, **kwargs) -> None:
8296    """
8297    Replace children of an expression with the result of a lambda fun(child) -> exp.
8298    """
8299    for k, v in tuple(expression.args.items()):
8300        is_list_arg = type(v) is list
8301
8302        child_nodes = v if is_list_arg else [v]
8303        new_child_nodes = []
8304
8305        for cn in child_nodes:
8306            if isinstance(cn, Expression):
8307                for child_node in ensure_collection(fun(cn, *args, **kwargs)):
8308                    new_child_nodes.append(child_node)
8309            else:
8310                new_child_nodes.append(cn)
8311
8312        expression.set(k, new_child_nodes if is_list_arg else seq_get(new_child_nodes, 0))
8313
8314
8315def replace_tree(
8316    expression: Expression,
8317    fun: t.Callable,
8318    prune: t.Optional[t.Callable[[Expression], bool]] = None,
8319) -> Expression:
8320    """
8321    Replace an entire tree with the result of function calls on each node.
8322
8323    This will be traversed in reverse dfs, so leaves first.
8324    If new nodes are created as a result of function calls, they will also be traversed.
8325    """
8326    stack = list(expression.dfs(prune=prune))
8327
8328    while stack:
8329        node = stack.pop()
8330        new_node = fun(node)
8331
8332        if new_node is not node:
8333            node.replace(new_node)
8334
8335            if isinstance(new_node, Expression):
8336                stack.append(new_node)
8337
8338    return new_node
8339
8340
8341def column_table_names(expression: Expression, exclude: str = "") -> t.Set[str]:
8342    """
8343    Return all table names referenced through columns in an expression.
8344
8345    Example:
8346        >>> import sqlglot
8347        >>> sorted(column_table_names(sqlglot.parse_one("a.b AND c.d AND c.e")))
8348        ['a', 'c']
8349
8350    Args:
8351        expression: expression to find table names.
8352        exclude: a table name to exclude
8353
8354    Returns:
8355        A list of unique names.
8356    """
8357    return {
8358        table
8359        for table in (column.table for column in expression.find_all(Column))
8360        if table and table != exclude
8361    }
8362
8363
8364def table_name(table: Table | str, dialect: DialectType = None, identify: bool = False) -> str:
8365    """Get the full name of a table as a string.
8366
8367    Args:
8368        table: Table expression node or string.
8369        dialect: The dialect to generate the table name for.
8370        identify: Determines when an identifier should be quoted. Possible values are:
8371            False (default): Never quote, except in cases where it's mandatory by the dialect.
8372            True: Always quote.
8373
8374    Examples:
8375        >>> from sqlglot import exp, parse_one
8376        >>> table_name(parse_one("select * from a.b.c").find(exp.Table))
8377        'a.b.c'
8378
8379    Returns:
8380        The table name.
8381    """
8382
8383    table = maybe_parse(table, into=Table, dialect=dialect)
8384
8385    if not table:
8386        raise ValueError(f"Cannot parse {table}")
8387
8388    return ".".join(
8389        (
8390            part.sql(dialect=dialect, identify=True, copy=False, comments=False)
8391            if identify or not SAFE_IDENTIFIER_RE.match(part.name)
8392            else part.name
8393        )
8394        for part in table.parts
8395    )
8396
8397
8398def normalize_table_name(table: str | Table, dialect: DialectType = None, copy: bool = True) -> str:
8399    """Returns a case normalized table name without quotes.
8400
8401    Args:
8402        table: the table to normalize
8403        dialect: the dialect to use for normalization rules
8404        copy: whether to copy the expression.
8405
8406    Examples:
8407        >>> normalize_table_name("`A-B`.c", dialect="bigquery")
8408        'A-B.c'
8409    """
8410    from sqlglot.optimizer.normalize_identifiers import normalize_identifiers
8411
8412    return ".".join(
8413        p.name
8414        for p in normalize_identifiers(
8415            to_table(table, dialect=dialect, copy=copy), dialect=dialect
8416        ).parts
8417    )
8418
8419
8420def replace_tables(
8421    expression: E, mapping: t.Dict[str, str], dialect: DialectType = None, copy: bool = True
8422) -> E:
8423    """Replace all tables in expression according to the mapping.
8424
8425    Args:
8426        expression: expression node to be transformed and replaced.
8427        mapping: mapping of table names.
8428        dialect: the dialect of the mapping table
8429        copy: whether to copy the expression.
8430
8431    Examples:
8432        >>> from sqlglot import exp, parse_one
8433        >>> replace_tables(parse_one("select * from a.b"), {"a.b": "c"}).sql()
8434        'SELECT * FROM c /* a.b */'
8435
8436    Returns:
8437        The mapped expression.
8438    """
8439
8440    mapping = {normalize_table_name(k, dialect=dialect): v for k, v in mapping.items()}
8441
8442    def _replace_tables(node: Expression) -> Expression:
8443        if isinstance(node, Table) and node.meta.get("replace") is not False:
8444            original = normalize_table_name(node, dialect=dialect)
8445            new_name = mapping.get(original)
8446
8447            if new_name:
8448                table = to_table(
8449                    new_name,
8450                    **{k: v for k, v in node.args.items() if k not in TABLE_PARTS},
8451                    dialect=dialect,
8452                )
8453                table.add_comments([original])
8454                return table
8455        return node
8456
8457    return expression.transform(_replace_tables, copy=copy)  # type: ignore
8458
8459
8460def replace_placeholders(expression: Expression, *args, **kwargs) -> Expression:
8461    """Replace placeholders in an expression.
8462
8463    Args:
8464        expression: expression node to be transformed and replaced.
8465        args: positional names that will substitute unnamed placeholders in the given order.
8466        kwargs: keyword arguments that will substitute named placeholders.
8467
8468    Examples:
8469        >>> from sqlglot import exp, parse_one
8470        >>> replace_placeholders(
8471        ...     parse_one("select * from :tbl where ? = ?"),
8472        ...     exp.to_identifier("str_col"), "b", tbl=exp.to_identifier("foo")
8473        ... ).sql()
8474        "SELECT * FROM foo WHERE str_col = 'b'"
8475
8476    Returns:
8477        The mapped expression.
8478    """
8479
8480    def _replace_placeholders(node: Expression, args, **kwargs) -> Expression:
8481        if isinstance(node, Placeholder):
8482            if node.this:
8483                new_name = kwargs.get(node.this)
8484                if new_name is not None:
8485                    return convert(new_name)
8486            else:
8487                try:
8488                    return convert(next(args))
8489                except StopIteration:
8490                    pass
8491        return node
8492
8493    return expression.transform(_replace_placeholders, iter(args), **kwargs)
8494
8495
8496def expand(
8497    expression: Expression,
8498    sources: t.Dict[str, Query],
8499    dialect: DialectType = None,
8500    copy: bool = True,
8501) -> Expression:
8502    """Transforms an expression by expanding all referenced sources into subqueries.
8503
8504    Examples:
8505        >>> from sqlglot import parse_one
8506        >>> expand(parse_one("select * from x AS z"), {"x": parse_one("select * from y")}).sql()
8507        'SELECT * FROM (SELECT * FROM y) AS z /* source: x */'
8508
8509        >>> expand(parse_one("select * from x AS z"), {"x": parse_one("select * from y"), "y": parse_one("select * from z")}).sql()
8510        'SELECT * FROM (SELECT * FROM (SELECT * FROM z) AS y /* source: y */) AS z /* source: x */'
8511
8512    Args:
8513        expression: The expression to expand.
8514        sources: A dictionary of name to Queries.
8515        dialect: The dialect of the sources dict.
8516        copy: Whether to copy the expression during transformation. Defaults to True.
8517
8518    Returns:
8519        The transformed expression.
8520    """
8521    sources = {normalize_table_name(k, dialect=dialect): v for k, v in sources.items()}
8522
8523    def _expand(node: Expression):
8524        if isinstance(node, Table):
8525            name = normalize_table_name(node, dialect=dialect)
8526            source = sources.get(name)
8527            if source:
8528                subquery = source.subquery(node.alias or name)
8529                subquery.comments = [f"source: {name}"]
8530                return subquery.transform(_expand, copy=False)
8531        return node
8532
8533    return expression.transform(_expand, copy=copy)
8534
8535
8536def func(name: str, *args, copy: bool = True, dialect: DialectType = None, **kwargs) -> Func:
8537    """
8538    Returns a Func expression.
8539
8540    Examples:
8541        >>> func("abs", 5).sql()
8542        'ABS(5)'
8543
8544        >>> func("cast", this=5, to=DataType.build("DOUBLE")).sql()
8545        'CAST(5 AS DOUBLE)'
8546
8547    Args:
8548        name: the name of the function to build.
8549        args: the args used to instantiate the function of interest.
8550        copy: whether to copy the argument expressions.
8551        dialect: the source dialect.
8552        kwargs: the kwargs used to instantiate the function of interest.
8553
8554    Note:
8555        The arguments `args` and `kwargs` are mutually exclusive.
8556
8557    Returns:
8558        An instance of the function of interest, or an anonymous function, if `name` doesn't
8559        correspond to an existing `sqlglot.expressions.Func` class.
8560    """
8561    if args and kwargs:
8562        raise ValueError("Can't use both args and kwargs to instantiate a function.")
8563
8564    from sqlglot.dialects.dialect import Dialect
8565
8566    dialect = Dialect.get_or_raise(dialect)
8567
8568    converted: t.List[Expression] = [maybe_parse(arg, dialect=dialect, copy=copy) for arg in args]
8569    kwargs = {key: maybe_parse(value, dialect=dialect, copy=copy) for key, value in kwargs.items()}
8570
8571    constructor = dialect.parser_class.FUNCTIONS.get(name.upper())
8572    if constructor:
8573        if converted:
8574            if "dialect" in constructor.__code__.co_varnames:
8575                function = constructor(converted, dialect=dialect)
8576            else:
8577                function = constructor(converted)
8578        elif constructor.__name__ == "from_arg_list":
8579            function = constructor.__self__(**kwargs)  # type: ignore
8580        else:
8581            constructor = FUNCTION_BY_NAME.get(name.upper())
8582            if constructor:
8583                function = constructor(**kwargs)
8584            else:
8585                raise ValueError(
8586                    f"Unable to convert '{name}' into a Func. Either manually construct "
8587                    "the Func expression of interest or parse the function call."
8588                )
8589    else:
8590        kwargs = kwargs or {"expressions": converted}
8591        function = Anonymous(this=name, **kwargs)
8592
8593    for error_message in function.error_messages(converted):
8594        raise ValueError(error_message)
8595
8596    return function
8597
8598
8599def case(
8600    expression: t.Optional[ExpOrStr] = None,
8601    **opts,
8602) -> Case:
8603    """
8604    Initialize a CASE statement.
8605
8606    Example:
8607        case().when("a = 1", "foo").else_("bar")
8608
8609    Args:
8610        expression: Optionally, the input expression (not all dialects support this)
8611        **opts: Extra keyword arguments for parsing `expression`
8612    """
8613    if expression is not None:
8614        this = maybe_parse(expression, **opts)
8615    else:
8616        this = None
8617    return Case(this=this, ifs=[])
8618
8619
8620def array(
8621    *expressions: ExpOrStr, copy: bool = True, dialect: DialectType = None, **kwargs
8622) -> Array:
8623    """
8624    Returns an array.
8625
8626    Examples:
8627        >>> array(1, 'x').sql()
8628        'ARRAY(1, x)'
8629
8630    Args:
8631        expressions: the expressions to add to the array.
8632        copy: whether to copy the argument expressions.
8633        dialect: the source dialect.
8634        kwargs: the kwargs used to instantiate the function of interest.
8635
8636    Returns:
8637        An array expression.
8638    """
8639    return Array(
8640        expressions=[
8641            maybe_parse(expression, copy=copy, dialect=dialect, **kwargs)
8642            for expression in expressions
8643        ]
8644    )
8645
8646
8647def tuple_(
8648    *expressions: ExpOrStr, copy: bool = True, dialect: DialectType = None, **kwargs
8649) -> Tuple:
8650    """
8651    Returns an tuple.
8652
8653    Examples:
8654        >>> tuple_(1, 'x').sql()
8655        '(1, x)'
8656
8657    Args:
8658        expressions: the expressions to add to the tuple.
8659        copy: whether to copy the argument expressions.
8660        dialect: the source dialect.
8661        kwargs: the kwargs used to instantiate the function of interest.
8662
8663    Returns:
8664        A tuple expression.
8665    """
8666    return Tuple(
8667        expressions=[
8668            maybe_parse(expression, copy=copy, dialect=dialect, **kwargs)
8669            for expression in expressions
8670        ]
8671    )
8672
8673
8674def true() -> Boolean:
8675    """
8676    Returns a true Boolean expression.
8677    """
8678    return Boolean(this=True)
8679
8680
8681def false() -> Boolean:
8682    """
8683    Returns a false Boolean expression.
8684    """
8685    return Boolean(this=False)
8686
8687
8688def null() -> Null:
8689    """
8690    Returns a Null expression.
8691    """
8692    return Null()
8693
8694
8695NONNULL_CONSTANTS = (
8696    Literal,
8697    Boolean,
8698)
8699
8700CONSTANTS = (
8701    Literal,
8702    Boolean,
8703    Null,
8704)
SQLGLOT_META = 'sqlglot.meta'
SQLGLOT_ANONYMOUS = 'sqlglot.anonymous'
TABLE_PARTS = ('this', 'db', 'catalog')
COLUMN_PARTS = ('this', 'table', 'db', 'catalog')
class Expression:
  68class Expression(metaclass=_Expression):
  69    """
  70    The base class for all expressions in a syntax tree. Each Expression encapsulates any necessary
  71    context, such as its child expressions, their names (arg keys), and whether a given child expression
  72    is optional or not.
  73
  74    Attributes:
  75        key: a unique key for each class in the Expression hierarchy. This is useful for hashing
  76            and representing expressions as strings.
  77        arg_types: determines the arguments (child nodes) supported by an expression. It maps
  78            arg keys to booleans that indicate whether the corresponding args are optional.
  79        parent: a reference to the parent expression (or None, in case of root expressions).
  80        arg_key: the arg key an expression is associated with, i.e. the name its parent expression
  81            uses to refer to it.
  82        index: the index of an expression if it is inside of a list argument in its parent.
  83        comments: a list of comments that are associated with a given expression. This is used in
  84            order to preserve comments when transpiling SQL code.
  85        type: the `sqlglot.expressions.DataType` type of an expression. This is inferred by the
  86            optimizer, in order to enable some transformations that require type information.
  87        meta: a dictionary that can be used to store useful metadata for a given expression.
  88
  89    Example:
  90        >>> class Foo(Expression):
  91        ...     arg_types = {"this": True, "expression": False}
  92
  93        The above definition informs us that Foo is an Expression that requires an argument called
  94        "this" and may also optionally receive an argument called "expression".
  95
  96    Args:
  97        args: a mapping used for retrieving the arguments of an expression, given their arg keys.
  98    """
  99
 100    key = "expression"
 101    arg_types = {"this": True}
 102    __slots__ = ("args", "parent", "arg_key", "index", "comments", "_type", "_meta", "_hash")
 103
 104    def __init__(self, **args: t.Any):
 105        self.args: t.Dict[str, t.Any] = args
 106        self.parent: t.Optional[Expression] = None
 107        self.arg_key: t.Optional[str] = None
 108        self.index: t.Optional[int] = None
 109        self.comments: t.Optional[t.List[str]] = None
 110        self._type: t.Optional[DataType] = None
 111        self._meta: t.Optional[t.Dict[str, t.Any]] = None
 112        self._hash: t.Optional[int] = None
 113
 114        for arg_key, value in self.args.items():
 115            self._set_parent(arg_key, value)
 116
 117    def __eq__(self, other) -> bool:
 118        return type(self) is type(other) and hash(self) == hash(other)
 119
 120    @property
 121    def hashable_args(self) -> t.Any:
 122        return frozenset(
 123            (k, tuple(_norm_arg(a) for a in v) if type(v) is list else _norm_arg(v))
 124            for k, v in self.args.items()
 125            if not (v is None or v is False or (type(v) is list and not v))
 126        )
 127
 128    def __hash__(self) -> int:
 129        if self._hash is not None:
 130            return self._hash
 131
 132        return hash((self.__class__, self.hashable_args))
 133
 134    @property
 135    def this(self) -> t.Any:
 136        """
 137        Retrieves the argument with key "this".
 138        """
 139        return self.args.get("this")
 140
 141    @property
 142    def expression(self) -> t.Any:
 143        """
 144        Retrieves the argument with key "expression".
 145        """
 146        return self.args.get("expression")
 147
 148    @property
 149    def expressions(self) -> t.List[t.Any]:
 150        """
 151        Retrieves the argument with key "expressions".
 152        """
 153        return self.args.get("expressions") or []
 154
 155    def text(self, key) -> str:
 156        """
 157        Returns a textual representation of the argument corresponding to "key". This can only be used
 158        for args that are strings or leaf Expression instances, such as identifiers and literals.
 159        """
 160        field = self.args.get(key)
 161        if isinstance(field, str):
 162            return field
 163        if isinstance(field, (Identifier, Literal, Var)):
 164            return field.this
 165        if isinstance(field, (Star, Null)):
 166            return field.name
 167        return ""
 168
 169    @property
 170    def is_string(self) -> bool:
 171        """
 172        Checks whether a Literal expression is a string.
 173        """
 174        return isinstance(self, Literal) and self.args["is_string"]
 175
 176    @property
 177    def is_number(self) -> bool:
 178        """
 179        Checks whether a Literal expression is a number.
 180        """
 181        return (isinstance(self, Literal) and not self.args["is_string"]) or (
 182            isinstance(self, Neg) and self.this.is_number
 183        )
 184
 185    def to_py(self) -> t.Any:
 186        """
 187        Returns a Python object equivalent of the SQL node.
 188        """
 189        raise ValueError(f"{self} cannot be converted to a Python object.")
 190
 191    @property
 192    def is_int(self) -> bool:
 193        """
 194        Checks whether an expression is an integer.
 195        """
 196        return self.is_number and isinstance(self.to_py(), int)
 197
 198    @property
 199    def is_star(self) -> bool:
 200        """Checks whether an expression is a star."""
 201        return isinstance(self, Star) or (isinstance(self, Column) and isinstance(self.this, Star))
 202
 203    @property
 204    def alias(self) -> str:
 205        """
 206        Returns the alias of the expression, or an empty string if it's not aliased.
 207        """
 208        if isinstance(self.args.get("alias"), TableAlias):
 209            return self.args["alias"].name
 210        return self.text("alias")
 211
 212    @property
 213    def alias_column_names(self) -> t.List[str]:
 214        table_alias = self.args.get("alias")
 215        if not table_alias:
 216            return []
 217        return [c.name for c in table_alias.args.get("columns") or []]
 218
 219    @property
 220    def name(self) -> str:
 221        return self.text("this")
 222
 223    @property
 224    def alias_or_name(self) -> str:
 225        return self.alias or self.name
 226
 227    @property
 228    def output_name(self) -> str:
 229        """
 230        Name of the output column if this expression is a selection.
 231
 232        If the Expression has no output name, an empty string is returned.
 233
 234        Example:
 235            >>> from sqlglot import parse_one
 236            >>> parse_one("SELECT a").expressions[0].output_name
 237            'a'
 238            >>> parse_one("SELECT b AS c").expressions[0].output_name
 239            'c'
 240            >>> parse_one("SELECT 1 + 2").expressions[0].output_name
 241            ''
 242        """
 243        return ""
 244
 245    @property
 246    def type(self) -> t.Optional[DataType]:
 247        return self._type
 248
 249    @type.setter
 250    def type(self, dtype: t.Optional[DataType | DataType.Type | str]) -> None:
 251        if dtype and not isinstance(dtype, DataType):
 252            dtype = DataType.build(dtype)
 253        self._type = dtype  # type: ignore
 254
 255    def is_type(self, *dtypes) -> bool:
 256        return self.type is not None and self.type.is_type(*dtypes)
 257
 258    def is_leaf(self) -> bool:
 259        return not any(isinstance(v, (Expression, list)) for v in self.args.values())
 260
 261    @property
 262    def meta(self) -> t.Dict[str, t.Any]:
 263        if self._meta is None:
 264            self._meta = {}
 265        return self._meta
 266
 267    def __deepcopy__(self, memo):
 268        root = self.__class__()
 269        stack = [(self, root)]
 270
 271        while stack:
 272            node, copy = stack.pop()
 273
 274            if node.comments is not None:
 275                copy.comments = deepcopy(node.comments)
 276            if node._type is not None:
 277                copy._type = deepcopy(node._type)
 278            if node._meta is not None:
 279                copy._meta = deepcopy(node._meta)
 280            if node._hash is not None:
 281                copy._hash = node._hash
 282
 283            for k, vs in node.args.items():
 284                if hasattr(vs, "parent"):
 285                    stack.append((vs, vs.__class__()))
 286                    copy.set(k, stack[-1][-1])
 287                elif type(vs) is list:
 288                    copy.args[k] = []
 289
 290                    for v in vs:
 291                        if hasattr(v, "parent"):
 292                            stack.append((v, v.__class__()))
 293                            copy.append(k, stack[-1][-1])
 294                        else:
 295                            copy.append(k, v)
 296                else:
 297                    copy.args[k] = vs
 298
 299        return root
 300
 301    def copy(self) -> Self:
 302        """
 303        Returns a deep copy of the expression.
 304        """
 305        return deepcopy(self)
 306
 307    def add_comments(self, comments: t.Optional[t.List[str]] = None, prepend: bool = False) -> None:
 308        if self.comments is None:
 309            self.comments = []
 310
 311        if comments:
 312            for comment in comments:
 313                _, *meta = comment.split(SQLGLOT_META)
 314                if meta:
 315                    for kv in "".join(meta).split(","):
 316                        k, *v = kv.split("=")
 317                        value = v[0].strip() if v else True
 318                        self.meta[k.strip()] = to_bool(value)
 319
 320                if not prepend:
 321                    self.comments.append(comment)
 322
 323            if prepend:
 324                self.comments = comments + self.comments
 325
 326    def pop_comments(self) -> t.List[str]:
 327        comments = self.comments or []
 328        self.comments = None
 329        return comments
 330
 331    def append(self, arg_key: str, value: t.Any) -> None:
 332        """
 333        Appends value to arg_key if it's a list or sets it as a new list.
 334
 335        Args:
 336            arg_key (str): name of the list expression arg
 337            value (Any): value to append to the list
 338        """
 339        if type(self.args.get(arg_key)) is not list:
 340            self.args[arg_key] = []
 341        self._set_parent(arg_key, value)
 342        values = self.args[arg_key]
 343        if hasattr(value, "parent"):
 344            value.index = len(values)
 345        values.append(value)
 346
 347    def set(
 348        self,
 349        arg_key: str,
 350        value: t.Any,
 351        index: t.Optional[int] = None,
 352        overwrite: bool = True,
 353    ) -> None:
 354        """
 355        Sets arg_key to value.
 356
 357        Args:
 358            arg_key: name of the expression arg.
 359            value: value to set the arg to.
 360            index: if the arg is a list, this specifies what position to add the value in it.
 361            overwrite: assuming an index is given, this determines whether to overwrite the
 362                list entry instead of only inserting a new value (i.e., like list.insert).
 363        """
 364        if index is not None:
 365            expressions = self.args.get(arg_key) or []
 366
 367            if seq_get(expressions, index) is None:
 368                return
 369            if value is None:
 370                expressions.pop(index)
 371                for v in expressions[index:]:
 372                    v.index = v.index - 1
 373                return
 374
 375            if isinstance(value, list):
 376                expressions.pop(index)
 377                expressions[index:index] = value
 378            elif overwrite:
 379                expressions[index] = value
 380            else:
 381                expressions.insert(index, value)
 382
 383            value = expressions
 384        elif value is None:
 385            self.args.pop(arg_key, None)
 386            return
 387
 388        self.args[arg_key] = value
 389        self._set_parent(arg_key, value, index)
 390
 391    def _set_parent(self, arg_key: str, value: t.Any, index: t.Optional[int] = None) -> None:
 392        if hasattr(value, "parent"):
 393            value.parent = self
 394            value.arg_key = arg_key
 395            value.index = index
 396        elif type(value) is list:
 397            for index, v in enumerate(value):
 398                if hasattr(v, "parent"):
 399                    v.parent = self
 400                    v.arg_key = arg_key
 401                    v.index = index
 402
 403    @property
 404    def depth(self) -> int:
 405        """
 406        Returns the depth of this tree.
 407        """
 408        if self.parent:
 409            return self.parent.depth + 1
 410        return 0
 411
 412    def iter_expressions(self, reverse: bool = False) -> t.Iterator[Expression]:
 413        """Yields the key and expression for all arguments, exploding list args."""
 414        # remove tuple when python 3.7 is deprecated
 415        for vs in reversed(tuple(self.args.values())) if reverse else self.args.values():  # type: ignore
 416            if type(vs) is list:
 417                for v in reversed(vs) if reverse else vs:  # type: ignore
 418                    if hasattr(v, "parent"):
 419                        yield v
 420            else:
 421                if hasattr(vs, "parent"):
 422                    yield vs
 423
 424    def find(self, *expression_types: t.Type[E], bfs: bool = True) -> t.Optional[E]:
 425        """
 426        Returns the first node in this tree which matches at least one of
 427        the specified types.
 428
 429        Args:
 430            expression_types: the expression type(s) to match.
 431            bfs: whether to search the AST using the BFS algorithm (DFS is used if false).
 432
 433        Returns:
 434            The node which matches the criteria or None if no such node was found.
 435        """
 436        return next(self.find_all(*expression_types, bfs=bfs), None)
 437
 438    def find_all(self, *expression_types: t.Type[E], bfs: bool = True) -> t.Iterator[E]:
 439        """
 440        Returns a generator object which visits all nodes in this tree and only
 441        yields those that match at least one of the specified expression types.
 442
 443        Args:
 444            expression_types: the expression type(s) to match.
 445            bfs: whether to search the AST using the BFS algorithm (DFS is used if false).
 446
 447        Returns:
 448            The generator object.
 449        """
 450        for expression in self.walk(bfs=bfs):
 451            if isinstance(expression, expression_types):
 452                yield expression
 453
 454    def find_ancestor(self, *expression_types: t.Type[E]) -> t.Optional[E]:
 455        """
 456        Returns a nearest parent matching expression_types.
 457
 458        Args:
 459            expression_types: the expression type(s) to match.
 460
 461        Returns:
 462            The parent node.
 463        """
 464        ancestor = self.parent
 465        while ancestor and not isinstance(ancestor, expression_types):
 466            ancestor = ancestor.parent
 467        return ancestor  # type: ignore
 468
 469    @property
 470    def parent_select(self) -> t.Optional[Select]:
 471        """
 472        Returns the parent select statement.
 473        """
 474        return self.find_ancestor(Select)
 475
 476    @property
 477    def same_parent(self) -> bool:
 478        """Returns if the parent is the same class as itself."""
 479        return type(self.parent) is self.__class__
 480
 481    def root(self) -> Expression:
 482        """
 483        Returns the root expression of this tree.
 484        """
 485        expression = self
 486        while expression.parent:
 487            expression = expression.parent
 488        return expression
 489
 490    def walk(
 491        self, bfs: bool = True, prune: t.Optional[t.Callable[[Expression], bool]] = None
 492    ) -> t.Iterator[Expression]:
 493        """
 494        Returns a generator object which visits all nodes in this tree.
 495
 496        Args:
 497            bfs: if set to True the BFS traversal order will be applied,
 498                otherwise the DFS traversal will be used instead.
 499            prune: callable that returns True if the generator should stop traversing
 500                this branch of the tree.
 501
 502        Returns:
 503            the generator object.
 504        """
 505        if bfs:
 506            yield from self.bfs(prune=prune)
 507        else:
 508            yield from self.dfs(prune=prune)
 509
 510    def dfs(
 511        self, prune: t.Optional[t.Callable[[Expression], bool]] = None
 512    ) -> t.Iterator[Expression]:
 513        """
 514        Returns a generator object which visits all nodes in this tree in
 515        the DFS (Depth-first) order.
 516
 517        Returns:
 518            The generator object.
 519        """
 520        stack = [self]
 521
 522        while stack:
 523            node = stack.pop()
 524
 525            yield node
 526
 527            if prune and prune(node):
 528                continue
 529
 530            for v in node.iter_expressions(reverse=True):
 531                stack.append(v)
 532
 533    def bfs(
 534        self, prune: t.Optional[t.Callable[[Expression], bool]] = None
 535    ) -> t.Iterator[Expression]:
 536        """
 537        Returns a generator object which visits all nodes in this tree in
 538        the BFS (Breadth-first) order.
 539
 540        Returns:
 541            The generator object.
 542        """
 543        queue = deque([self])
 544
 545        while queue:
 546            node = queue.popleft()
 547
 548            yield node
 549
 550            if prune and prune(node):
 551                continue
 552
 553            for v in node.iter_expressions():
 554                queue.append(v)
 555
 556    def unnest(self):
 557        """
 558        Returns the first non parenthesis child or self.
 559        """
 560        expression = self
 561        while type(expression) is Paren:
 562            expression = expression.this
 563        return expression
 564
 565    def unalias(self):
 566        """
 567        Returns the inner expression if this is an Alias.
 568        """
 569        if isinstance(self, Alias):
 570            return self.this
 571        return self
 572
 573    def unnest_operands(self):
 574        """
 575        Returns unnested operands as a tuple.
 576        """
 577        return tuple(arg.unnest() for arg in self.iter_expressions())
 578
 579    def flatten(self, unnest=True):
 580        """
 581        Returns a generator which yields child nodes whose parents are the same class.
 582
 583        A AND B AND C -> [A, B, C]
 584        """
 585        for node in self.dfs(prune=lambda n: n.parent and type(n) is not self.__class__):
 586            if type(node) is not self.__class__:
 587                yield node.unnest() if unnest and not isinstance(node, Subquery) else node
 588
 589    def __str__(self) -> str:
 590        return self.sql()
 591
 592    def __repr__(self) -> str:
 593        return _to_s(self)
 594
 595    def to_s(self) -> str:
 596        """
 597        Same as __repr__, but includes additional information which can be useful
 598        for debugging, like empty or missing args and the AST nodes' object IDs.
 599        """
 600        return _to_s(self, verbose=True)
 601
 602    def sql(self, dialect: DialectType = None, **opts) -> str:
 603        """
 604        Returns SQL string representation of this tree.
 605
 606        Args:
 607            dialect: the dialect of the output SQL string (eg. "spark", "hive", "presto", "mysql").
 608            opts: other `sqlglot.generator.Generator` options.
 609
 610        Returns:
 611            The SQL string.
 612        """
 613        from sqlglot.dialects import Dialect
 614
 615        return Dialect.get_or_raise(dialect).generate(self, **opts)
 616
 617    def transform(self, fun: t.Callable, *args: t.Any, copy: bool = True, **kwargs) -> Expression:
 618        """
 619        Visits all tree nodes (excluding already transformed ones)
 620        and applies the given transformation function to each node.
 621
 622        Args:
 623            fun: a function which takes a node as an argument and returns a
 624                new transformed node or the same node without modifications. If the function
 625                returns None, then the corresponding node will be removed from the syntax tree.
 626            copy: if set to True a new tree instance is constructed, otherwise the tree is
 627                modified in place.
 628
 629        Returns:
 630            The transformed tree.
 631        """
 632        root = None
 633        new_node = None
 634
 635        for node in (self.copy() if copy else self).dfs(prune=lambda n: n is not new_node):
 636            parent, arg_key, index = node.parent, node.arg_key, node.index
 637            new_node = fun(node, *args, **kwargs)
 638
 639            if not root:
 640                root = new_node
 641            elif parent and arg_key and new_node is not node:
 642                parent.set(arg_key, new_node, index)
 643
 644        assert root
 645        return root.assert_is(Expression)
 646
 647    @t.overload
 648    def replace(self, expression: E) -> E: ...
 649
 650    @t.overload
 651    def replace(self, expression: None) -> None: ...
 652
 653    def replace(self, expression):
 654        """
 655        Swap out this expression with a new expression.
 656
 657        For example::
 658
 659            >>> tree = Select().select("x").from_("tbl")
 660            >>> tree.find(Column).replace(column("y"))
 661            Column(
 662              this=Identifier(this=y, quoted=False))
 663            >>> tree.sql()
 664            'SELECT y FROM tbl'
 665
 666        Args:
 667            expression: new node
 668
 669        Returns:
 670            The new expression or expressions.
 671        """
 672        parent = self.parent
 673
 674        if not parent or parent is expression:
 675            return expression
 676
 677        key = self.arg_key
 678        value = parent.args.get(key)
 679
 680        if type(expression) is list and isinstance(value, Expression):
 681            # We are trying to replace an Expression with a list, so it's assumed that
 682            # the intention was to really replace the parent of this expression.
 683            value.parent.replace(expression)
 684        else:
 685            parent.set(key, expression, self.index)
 686
 687        if expression is not self:
 688            self.parent = None
 689            self.arg_key = None
 690            self.index = None
 691
 692        return expression
 693
 694    def pop(self: E) -> E:
 695        """
 696        Remove this expression from its AST.
 697
 698        Returns:
 699            The popped expression.
 700        """
 701        self.replace(None)
 702        return self
 703
 704    def assert_is(self, type_: t.Type[E]) -> E:
 705        """
 706        Assert that this `Expression` is an instance of `type_`.
 707
 708        If it is NOT an instance of `type_`, this raises an assertion error.
 709        Otherwise, this returns this expression.
 710
 711        Examples:
 712            This is useful for type security in chained expressions:
 713
 714            >>> import sqlglot
 715            >>> sqlglot.parse_one("SELECT x from y").assert_is(Select).select("z").sql()
 716            'SELECT x, z FROM y'
 717        """
 718        if not isinstance(self, type_):
 719            raise AssertionError(f"{self} is not {type_}.")
 720        return self
 721
 722    def error_messages(self, args: t.Optional[t.Sequence] = None) -> t.List[str]:
 723        """
 724        Checks if this expression is valid (e.g. all mandatory args are set).
 725
 726        Args:
 727            args: a sequence of values that were used to instantiate a Func expression. This is used
 728                to check that the provided arguments don't exceed the function argument limit.
 729
 730        Returns:
 731            A list of error messages for all possible errors that were found.
 732        """
 733        errors: t.List[str] = []
 734
 735        for k in self.args:
 736            if k not in self.arg_types:
 737                errors.append(f"Unexpected keyword: '{k}' for {self.__class__}")
 738        for k, mandatory in self.arg_types.items():
 739            v = self.args.get(k)
 740            if mandatory and (v is None or (isinstance(v, list) and not v)):
 741                errors.append(f"Required keyword: '{k}' missing for {self.__class__}")
 742
 743        if (
 744            args
 745            and isinstance(self, Func)
 746            and len(args) > len(self.arg_types)
 747            and not self.is_var_len_args
 748        ):
 749            errors.append(
 750                f"The number of provided arguments ({len(args)}) is greater than "
 751                f"the maximum number of supported arguments ({len(self.arg_types)})"
 752            )
 753
 754        return errors
 755
 756    def dump(self):
 757        """
 758        Dump this Expression to a JSON-serializable dict.
 759        """
 760        from sqlglot.serde import dump
 761
 762        return dump(self)
 763
 764    @classmethod
 765    def load(cls, obj):
 766        """
 767        Load a dict (as returned by `Expression.dump`) into an Expression instance.
 768        """
 769        from sqlglot.serde import load
 770
 771        return load(obj)
 772
 773    def and_(
 774        self,
 775        *expressions: t.Optional[ExpOrStr],
 776        dialect: DialectType = None,
 777        copy: bool = True,
 778        wrap: bool = True,
 779        **opts,
 780    ) -> Condition:
 781        """
 782        AND this condition with one or multiple expressions.
 783
 784        Example:
 785            >>> condition("x=1").and_("y=1").sql()
 786            'x = 1 AND y = 1'
 787
 788        Args:
 789            *expressions: the SQL code strings to parse.
 790                If an `Expression` instance is passed, it will be used as-is.
 791            dialect: the dialect used to parse the input expression.
 792            copy: whether to copy the involved expressions (only applies to Expressions).
 793            wrap: whether to wrap the operands in `Paren`s. This is true by default to avoid
 794                precedence issues, but can be turned off when the produced AST is too deep and
 795                causes recursion-related issues.
 796            opts: other options to use to parse the input expressions.
 797
 798        Returns:
 799            The new And condition.
 800        """
 801        return and_(self, *expressions, dialect=dialect, copy=copy, wrap=wrap, **opts)
 802
 803    def or_(
 804        self,
 805        *expressions: t.Optional[ExpOrStr],
 806        dialect: DialectType = None,
 807        copy: bool = True,
 808        wrap: bool = True,
 809        **opts,
 810    ) -> Condition:
 811        """
 812        OR this condition with one or multiple expressions.
 813
 814        Example:
 815            >>> condition("x=1").or_("y=1").sql()
 816            'x = 1 OR y = 1'
 817
 818        Args:
 819            *expressions: the SQL code strings to parse.
 820                If an `Expression` instance is passed, it will be used as-is.
 821            dialect: the dialect used to parse the input expression.
 822            copy: whether to copy the involved expressions (only applies to Expressions).
 823            wrap: whether to wrap the operands in `Paren`s. This is true by default to avoid
 824                precedence issues, but can be turned off when the produced AST is too deep and
 825                causes recursion-related issues.
 826            opts: other options to use to parse the input expressions.
 827
 828        Returns:
 829            The new Or condition.
 830        """
 831        return or_(self, *expressions, dialect=dialect, copy=copy, wrap=wrap, **opts)
 832
 833    def not_(self, copy: bool = True):
 834        """
 835        Wrap this condition with NOT.
 836
 837        Example:
 838            >>> condition("x=1").not_().sql()
 839            'NOT x = 1'
 840
 841        Args:
 842            copy: whether to copy this object.
 843
 844        Returns:
 845            The new Not instance.
 846        """
 847        return not_(self, copy=copy)
 848
 849    def as_(
 850        self,
 851        alias: str | Identifier,
 852        quoted: t.Optional[bool] = None,
 853        dialect: DialectType = None,
 854        copy: bool = True,
 855        **opts,
 856    ) -> Alias:
 857        return alias_(self, alias, quoted=quoted, dialect=dialect, copy=copy, **opts)
 858
 859    def _binop(self, klass: t.Type[E], other: t.Any, reverse: bool = False) -> E:
 860        this = self.copy()
 861        other = convert(other, copy=True)
 862        if not isinstance(this, klass) and not isinstance(other, klass):
 863            this = _wrap(this, Binary)
 864            other = _wrap(other, Binary)
 865        if reverse:
 866            return klass(this=other, expression=this)
 867        return klass(this=this, expression=other)
 868
 869    def __getitem__(self, other: ExpOrStr | t.Tuple[ExpOrStr]) -> Bracket:
 870        return Bracket(
 871            this=self.copy(), expressions=[convert(e, copy=True) for e in ensure_list(other)]
 872        )
 873
 874    def __iter__(self) -> t.Iterator:
 875        if "expressions" in self.arg_types:
 876            return iter(self.args.get("expressions") or [])
 877        # We define this because __getitem__ converts Expression into an iterable, which is
 878        # problematic because one can hit infinite loops if they do "for x in some_expr: ..."
 879        # See: https://peps.python.org/pep-0234/
 880        raise TypeError(f"'{self.__class__.__name__}' object is not iterable")
 881
 882    def isin(
 883        self,
 884        *expressions: t.Any,
 885        query: t.Optional[ExpOrStr] = None,
 886        unnest: t.Optional[ExpOrStr] | t.Collection[ExpOrStr] = None,
 887        copy: bool = True,
 888        **opts,
 889    ) -> In:
 890        subquery = maybe_parse(query, copy=copy, **opts) if query else None
 891        if subquery and not isinstance(subquery, Subquery):
 892            subquery = subquery.subquery(copy=False)
 893
 894        return In(
 895            this=maybe_copy(self, copy),
 896            expressions=[convert(e, copy=copy) for e in expressions],
 897            query=subquery,
 898            unnest=(
 899                Unnest(
 900                    expressions=[
 901                        maybe_parse(t.cast(ExpOrStr, e), copy=copy, **opts)
 902                        for e in ensure_list(unnest)
 903                    ]
 904                )
 905                if unnest
 906                else None
 907            ),
 908        )
 909
 910    def between(self, low: t.Any, high: t.Any, copy: bool = True, **opts) -> Between:
 911        return Between(
 912            this=maybe_copy(self, copy),
 913            low=convert(low, copy=copy, **opts),
 914            high=convert(high, copy=copy, **opts),
 915        )
 916
 917    def is_(self, other: ExpOrStr) -> Is:
 918        return self._binop(Is, other)
 919
 920    def like(self, other: ExpOrStr) -> Like:
 921        return self._binop(Like, other)
 922
 923    def ilike(self, other: ExpOrStr) -> ILike:
 924        return self._binop(ILike, other)
 925
 926    def eq(self, other: t.Any) -> EQ:
 927        return self._binop(EQ, other)
 928
 929    def neq(self, other: t.Any) -> NEQ:
 930        return self._binop(NEQ, other)
 931
 932    def rlike(self, other: ExpOrStr) -> RegexpLike:
 933        return self._binop(RegexpLike, other)
 934
 935    def div(self, other: ExpOrStr, typed: bool = False, safe: bool = False) -> Div:
 936        div = self._binop(Div, other)
 937        div.args["typed"] = typed
 938        div.args["safe"] = safe
 939        return div
 940
 941    def asc(self, nulls_first: bool = True) -> Ordered:
 942        return Ordered(this=self.copy(), nulls_first=nulls_first)
 943
 944    def desc(self, nulls_first: bool = False) -> Ordered:
 945        return Ordered(this=self.copy(), desc=True, nulls_first=nulls_first)
 946
 947    def __lt__(self, other: t.Any) -> LT:
 948        return self._binop(LT, other)
 949
 950    def __le__(self, other: t.Any) -> LTE:
 951        return self._binop(LTE, other)
 952
 953    def __gt__(self, other: t.Any) -> GT:
 954        return self._binop(GT, other)
 955
 956    def __ge__(self, other: t.Any) -> GTE:
 957        return self._binop(GTE, other)
 958
 959    def __add__(self, other: t.Any) -> Add:
 960        return self._binop(Add, other)
 961
 962    def __radd__(self, other: t.Any) -> Add:
 963        return self._binop(Add, other, reverse=True)
 964
 965    def __sub__(self, other: t.Any) -> Sub:
 966        return self._binop(Sub, other)
 967
 968    def __rsub__(self, other: t.Any) -> Sub:
 969        return self._binop(Sub, other, reverse=True)
 970
 971    def __mul__(self, other: t.Any) -> Mul:
 972        return self._binop(Mul, other)
 973
 974    def __rmul__(self, other: t.Any) -> Mul:
 975        return self._binop(Mul, other, reverse=True)
 976
 977    def __truediv__(self, other: t.Any) -> Div:
 978        return self._binop(Div, other)
 979
 980    def __rtruediv__(self, other: t.Any) -> Div:
 981        return self._binop(Div, other, reverse=True)
 982
 983    def __floordiv__(self, other: t.Any) -> IntDiv:
 984        return self._binop(IntDiv, other)
 985
 986    def __rfloordiv__(self, other: t.Any) -> IntDiv:
 987        return self._binop(IntDiv, other, reverse=True)
 988
 989    def __mod__(self, other: t.Any) -> Mod:
 990        return self._binop(Mod, other)
 991
 992    def __rmod__(self, other: t.Any) -> Mod:
 993        return self._binop(Mod, other, reverse=True)
 994
 995    def __pow__(self, other: t.Any) -> Pow:
 996        return self._binop(Pow, other)
 997
 998    def __rpow__(self, other: t.Any) -> Pow:
 999        return self._binop(Pow, other, reverse=True)
1000
1001    def __and__(self, other: t.Any) -> And:
1002        return self._binop(And, other)
1003
1004    def __rand__(self, other: t.Any) -> And:
1005        return self._binop(And, other, reverse=True)
1006
1007    def __or__(self, other: t.Any) -> Or:
1008        return self._binop(Or, other)
1009
1010    def __ror__(self, other: t.Any) -> Or:
1011        return self._binop(Or, other, reverse=True)
1012
1013    def __neg__(self) -> Neg:
1014        return Neg(this=_wrap(self.copy(), Binary))
1015
1016    def __invert__(self) -> Not:
1017        return not_(self.copy())

The base class for all expressions in a syntax tree. Each Expression encapsulates any necessary context, such as its child expressions, their names (arg keys), and whether a given child expression is optional or not.

Attributes:
  • key: a unique key for each class in the Expression hierarchy. This is useful for hashing and representing expressions as strings.
  • arg_types: determines the arguments (child nodes) supported by an expression. It maps arg keys to booleans that indicate whether the corresponding args are optional.
  • parent: a reference to the parent expression (or None, in case of root expressions).
  • arg_key: the arg key an expression is associated with, i.e. the name its parent expression uses to refer to it.
  • index: the index of an expression if it is inside of a list argument in its parent.
  • comments: a list of comments that are associated with a given expression. This is used in order to preserve comments when transpiling SQL code.
  • type: the sqlglot.expressions.DataType type of an expression. This is inferred by the optimizer, in order to enable some transformations that require type information.
  • meta: a dictionary that can be used to store useful metadata for a given expression.
Example:
>>> class Foo(Expression):
...     arg_types = {"this": True, "expression": False}

The above definition informs us that Foo is an Expression that requires an argument called "this" and may also optionally receive an argument called "expression".

Arguments:
  • args: a mapping used for retrieving the arguments of an expression, given their arg keys.
Expression(**args: Any)
104    def __init__(self, **args: t.Any):
105        self.args: t.Dict[str, t.Any] = args
106        self.parent: t.Optional[Expression] = None
107        self.arg_key: t.Optional[str] = None
108        self.index: t.Optional[int] = None
109        self.comments: t.Optional[t.List[str]] = None
110        self._type: t.Optional[DataType] = None
111        self._meta: t.Optional[t.Dict[str, t.Any]] = None
112        self._hash: t.Optional[int] = None
113
114        for arg_key, value in self.args.items():
115            self._set_parent(arg_key, value)
key = 'expression'
arg_types = {'this': True}
args: Dict[str, Any]
parent: Optional[Expression]
arg_key: Optional[str]
index: Optional[int]
comments: Optional[List[str]]
hashable_args: Any
120    @property
121    def hashable_args(self) -> t.Any:
122        return frozenset(
123            (k, tuple(_norm_arg(a) for a in v) if type(v) is list else _norm_arg(v))
124            for k, v in self.args.items()
125            if not (v is None or v is False or (type(v) is list and not v))
126        )
this: Any
134    @property
135    def this(self) -> t.Any:
136        """
137        Retrieves the argument with key "this".
138        """
139        return self.args.get("this")

Retrieves the argument with key "this".

expression: Any
141    @property
142    def expression(self) -> t.Any:
143        """
144        Retrieves the argument with key "expression".
145        """
146        return self.args.get("expression")

Retrieves the argument with key "expression".

expressions: List[Any]
148    @property
149    def expressions(self) -> t.List[t.Any]:
150        """
151        Retrieves the argument with key "expressions".
152        """
153        return self.args.get("expressions") or []

Retrieves the argument with key "expressions".

def text(self, key) -> str:
155    def text(self, key) -> str:
156        """
157        Returns a textual representation of the argument corresponding to "key". This can only be used
158        for args that are strings or leaf Expression instances, such as identifiers and literals.
159        """
160        field = self.args.get(key)
161        if isinstance(field, str):
162            return field
163        if isinstance(field, (Identifier, Literal, Var)):
164            return field.this
165        if isinstance(field, (Star, Null)):
166            return field.name
167        return ""

Returns a textual representation of the argument corresponding to "key". This can only be used for args that are strings or leaf Expression instances, such as identifiers and literals.

is_string: bool
169    @property
170    def is_string(self) -> bool:
171        """
172        Checks whether a Literal expression is a string.
173        """
174        return isinstance(self, Literal) and self.args["is_string"]

Checks whether a Literal expression is a string.

is_number: bool
176    @property
177    def is_number(self) -> bool:
178        """
179        Checks whether a Literal expression is a number.
180        """
181        return (isinstance(self, Literal) and not self.args["is_string"]) or (
182            isinstance(self, Neg) and self.this.is_number
183        )

Checks whether a Literal expression is a number.

def to_py(self) -> Any:
185    def to_py(self) -> t.Any:
186        """
187        Returns a Python object equivalent of the SQL node.
188        """
189        raise ValueError(f"{self} cannot be converted to a Python object.")

Returns a Python object equivalent of the SQL node.

is_int: bool
191    @property
192    def is_int(self) -> bool:
193        """
194        Checks whether an expression is an integer.
195        """
196        return self.is_number and isinstance(self.to_py(), int)

Checks whether an expression is an integer.

is_star: bool
198    @property
199    def is_star(self) -> bool:
200        """Checks whether an expression is a star."""
201        return isinstance(self, Star) or (isinstance(self, Column) and isinstance(self.this, Star))

Checks whether an expression is a star.

alias: str
203    @property
204    def alias(self) -> str:
205        """
206        Returns the alias of the expression, or an empty string if it's not aliased.
207        """
208        if isinstance(self.args.get("alias"), TableAlias):
209            return self.args["alias"].name
210        return self.text("alias")

Returns the alias of the expression, or an empty string if it's not aliased.

alias_column_names: List[str]
212    @property
213    def alias_column_names(self) -> t.List[str]:
214        table_alias = self.args.get("alias")
215        if not table_alias:
216            return []
217        return [c.name for c in table_alias.args.get("columns") or []]
name: str
219    @property
220    def name(self) -> str:
221        return self.text("this")
alias_or_name: str
223    @property
224    def alias_or_name(self) -> str:
225        return self.alias or self.name
output_name: str
227    @property
228    def output_name(self) -> str:
229        """
230        Name of the output column if this expression is a selection.
231
232        If the Expression has no output name, an empty string is returned.
233
234        Example:
235            >>> from sqlglot import parse_one
236            >>> parse_one("SELECT a").expressions[0].output_name
237            'a'
238            >>> parse_one("SELECT b AS c").expressions[0].output_name
239            'c'
240            >>> parse_one("SELECT 1 + 2").expressions[0].output_name
241            ''
242        """
243        return ""

Name of the output column if this expression is a selection.

If the Expression has no output name, an empty string is returned.

Example:
>>> from sqlglot import parse_one
>>> parse_one("SELECT a")sqlglot.expressions[0].output_name
'a'
>>> parse_one("SELECT b AS c")sqlglot.expressions[0].output_name
'c'
>>> parse_one("SELECT 1 + 2")sqlglot.expressions[0].output_name
''
type: Optional[DataType]
245    @property
246    def type(self) -> t.Optional[DataType]:
247        return self._type
def is_type(self, *dtypes) -> bool:
255    def is_type(self, *dtypes) -> bool:
256        return self.type is not None and self.type.is_type(*dtypes)
def is_leaf(self) -> bool:
258    def is_leaf(self) -> bool:
259        return not any(isinstance(v, (Expression, list)) for v in self.args.values())
meta: Dict[str, Any]
261    @property
262    def meta(self) -> t.Dict[str, t.Any]:
263        if self._meta is None:
264            self._meta = {}
265        return self._meta
def copy(self) -> typing_extensions.Self:
301    def copy(self) -> Self:
302        """
303        Returns a deep copy of the expression.
304        """
305        return deepcopy(self)

Returns a deep copy of the expression.

def add_comments( self, comments: Optional[List[str]] = None, prepend: bool = False) -> None:
307    def add_comments(self, comments: t.Optional[t.List[str]] = None, prepend: bool = False) -> None:
308        if self.comments is None:
309            self.comments = []
310
311        if comments:
312            for comment in comments:
313                _, *meta = comment.split(SQLGLOT_META)
314                if meta:
315                    for kv in "".join(meta).split(","):
316                        k, *v = kv.split("=")
317                        value = v[0].strip() if v else True
318                        self.meta[k.strip()] = to_bool(value)
319
320                if not prepend:
321                    self.comments.append(comment)
322
323            if prepend:
324                self.comments = comments + self.comments
def pop_comments(self) -> List[str]:
326    def pop_comments(self) -> t.List[str]:
327        comments = self.comments or []
328        self.comments = None
329        return comments
def append(self, arg_key: str, value: Any) -> None:
331    def append(self, arg_key: str, value: t.Any) -> None:
332        """
333        Appends value to arg_key if it's a list or sets it as a new list.
334
335        Args:
336            arg_key (str): name of the list expression arg
337            value (Any): value to append to the list
338        """
339        if type(self.args.get(arg_key)) is not list:
340            self.args[arg_key] = []
341        self._set_parent(arg_key, value)
342        values = self.args[arg_key]
343        if hasattr(value, "parent"):
344            value.index = len(values)
345        values.append(value)

Appends value to arg_key if it's a list or sets it as a new list.

Arguments:
  • arg_key (str): name of the list expression arg
  • value (Any): value to append to the list
def set( self, arg_key: str, value: Any, index: Optional[int] = None, overwrite: bool = True) -> None:
347    def set(
348        self,
349        arg_key: str,
350        value: t.Any,
351        index: t.Optional[int] = None,
352        overwrite: bool = True,
353    ) -> None:
354        """
355        Sets arg_key to value.
356
357        Args:
358            arg_key: name of the expression arg.
359            value: value to set the arg to.
360            index: if the arg is a list, this specifies what position to add the value in it.
361            overwrite: assuming an index is given, this determines whether to overwrite the
362                list entry instead of only inserting a new value (i.e., like list.insert).
363        """
364        if index is not None:
365            expressions = self.args.get(arg_key) or []
366
367            if seq_get(expressions, index) is None:
368                return
369            if value is None:
370                expressions.pop(index)
371                for v in expressions[index:]:
372                    v.index = v.index - 1
373                return
374
375            if isinstance(value, list):
376                expressions.pop(index)
377                expressions[index:index] = value
378            elif overwrite:
379                expressions[index] = value
380            else:
381                expressions.insert(index, value)
382
383            value = expressions
384        elif value is None:
385            self.args.pop(arg_key, None)
386            return
387
388        self.args[arg_key] = value
389        self._set_parent(arg_key, value, index)

Sets arg_key to value.

Arguments:
  • arg_key: name of the expression arg.
  • value: value to set the arg to.
  • index: if the arg is a list, this specifies what position to add the value in it.
  • overwrite: assuming an index is given, this determines whether to overwrite the list entry instead of only inserting a new value (i.e., like list.insert).
depth: int
403    @property
404    def depth(self) -> int:
405        """
406        Returns the depth of this tree.
407        """
408        if self.parent:
409            return self.parent.depth + 1
410        return 0

Returns the depth of this tree.

def iter_expressions(self, reverse: bool = False) -> Iterator[Expression]:
412    def iter_expressions(self, reverse: bool = False) -> t.Iterator[Expression]:
413        """Yields the key and expression for all arguments, exploding list args."""
414        # remove tuple when python 3.7 is deprecated
415        for vs in reversed(tuple(self.args.values())) if reverse else self.args.values():  # type: ignore
416            if type(vs) is list:
417                for v in reversed(vs) if reverse else vs:  # type: ignore
418                    if hasattr(v, "parent"):
419                        yield v
420            else:
421                if hasattr(vs, "parent"):
422                    yield vs

Yields the key and expression for all arguments, exploding list args.

def find(self, *expression_types: Type[~E], bfs: bool = True) -> Optional[~E]:
424    def find(self, *expression_types: t.Type[E], bfs: bool = True) -> t.Optional[E]:
425        """
426        Returns the first node in this tree which matches at least one of
427        the specified types.
428
429        Args:
430            expression_types: the expression type(s) to match.
431            bfs: whether to search the AST using the BFS algorithm (DFS is used if false).
432
433        Returns:
434            The node which matches the criteria or None if no such node was found.
435        """
436        return next(self.find_all(*expression_types, bfs=bfs), None)

Returns the first node in this tree which matches at least one of the specified types.

Arguments:
  • expression_types: the expression type(s) to match.
  • bfs: whether to search the AST using the BFS algorithm (DFS is used if false).
Returns:

The node which matches the criteria or None if no such node was found.

def find_all(self, *expression_types: Type[~E], bfs: bool = True) -> Iterator[~E]:
438    def find_all(self, *expression_types: t.Type[E], bfs: bool = True) -> t.Iterator[E]:
439        """
440        Returns a generator object which visits all nodes in this tree and only
441        yields those that match at least one of the specified expression types.
442
443        Args:
444            expression_types: the expression type(s) to match.
445            bfs: whether to search the AST using the BFS algorithm (DFS is used if false).
446
447        Returns:
448            The generator object.
449        """
450        for expression in self.walk(bfs=bfs):
451            if isinstance(expression, expression_types):
452                yield expression

Returns a generator object which visits all nodes in this tree and only yields those that match at least one of the specified expression types.

Arguments:
  • expression_types: the expression type(s) to match.
  • bfs: whether to search the AST using the BFS algorithm (DFS is used if false).
Returns:

The generator object.

def find_ancestor(self, *expression_types: Type[~E]) -> Optional[~E]:
454    def find_ancestor(self, *expression_types: t.Type[E]) -> t.Optional[E]:
455        """
456        Returns a nearest parent matching expression_types.
457
458        Args:
459            expression_types: the expression type(s) to match.
460
461        Returns:
462            The parent node.
463        """
464        ancestor = self.parent
465        while ancestor and not isinstance(ancestor, expression_types):
466            ancestor = ancestor.parent
467        return ancestor  # type: ignore

Returns a nearest parent matching expression_types.

Arguments:
  • expression_types: the expression type(s) to match.
Returns:

The parent node.

parent_select: Optional[Select]
469    @property
470    def parent_select(self) -> t.Optional[Select]:
471        """
472        Returns the parent select statement.
473        """
474        return self.find_ancestor(Select)

Returns the parent select statement.

same_parent: bool
476    @property
477    def same_parent(self) -> bool:
478        """Returns if the parent is the same class as itself."""
479        return type(self.parent) is self.__class__

Returns if the parent is the same class as itself.

def root(self) -> Expression:
481    def root(self) -> Expression:
482        """
483        Returns the root expression of this tree.
484        """
485        expression = self
486        while expression.parent:
487            expression = expression.parent
488        return expression

Returns the root expression of this tree.

def walk( self, bfs: bool = True, prune: Optional[Callable[[Expression], bool]] = None) -> Iterator[Expression]:
490    def walk(
491        self, bfs: bool = True, prune: t.Optional[t.Callable[[Expression], bool]] = None
492    ) -> t.Iterator[Expression]:
493        """
494        Returns a generator object which visits all nodes in this tree.
495
496        Args:
497            bfs: if set to True the BFS traversal order will be applied,
498                otherwise the DFS traversal will be used instead.
499            prune: callable that returns True if the generator should stop traversing
500                this branch of the tree.
501
502        Returns:
503            the generator object.
504        """
505        if bfs:
506            yield from self.bfs(prune=prune)
507        else:
508            yield from self.dfs(prune=prune)

Returns a generator object which visits all nodes in this tree.

Arguments:
  • bfs: if set to True the BFS traversal order will be applied, otherwise the DFS traversal will be used instead.
  • prune: callable that returns True if the generator should stop traversing this branch of the tree.
Returns:

the generator object.

def dfs( self, prune: Optional[Callable[[Expression], bool]] = None) -> Iterator[Expression]:
510    def dfs(
511        self, prune: t.Optional[t.Callable[[Expression], bool]] = None
512    ) -> t.Iterator[Expression]:
513        """
514        Returns a generator object which visits all nodes in this tree in
515        the DFS (Depth-first) order.
516
517        Returns:
518            The generator object.
519        """
520        stack = [self]
521
522        while stack:
523            node = stack.pop()
524
525            yield node
526
527            if prune and prune(node):
528                continue
529
530            for v in node.iter_expressions(reverse=True):
531                stack.append(v)

Returns a generator object which visits all nodes in this tree in the DFS (Depth-first) order.

Returns:

The generator object.

def bfs( self, prune: Optional[Callable[[Expression], bool]] = None) -> Iterator[Expression]:
533    def bfs(
534        self, prune: t.Optional[t.Callable[[Expression], bool]] = None
535    ) -> t.Iterator[Expression]:
536        """
537        Returns a generator object which visits all nodes in this tree in
538        the BFS (Breadth-first) order.
539
540        Returns:
541            The generator object.
542        """
543        queue = deque([self])
544
545        while queue:
546            node = queue.popleft()
547
548            yield node
549
550            if prune and prune(node):
551                continue
552
553            for v in node.iter_expressions():
554                queue.append(v)

Returns a generator object which visits all nodes in this tree in the BFS (Breadth-first) order.

Returns:

The generator object.

def unnest(self):
556    def unnest(self):
557        """
558        Returns the first non parenthesis child or self.
559        """
560        expression = self
561        while type(expression) is Paren:
562            expression = expression.this
563        return expression

Returns the first non parenthesis child or self.

def unalias(self):
565    def unalias(self):
566        """
567        Returns the inner expression if this is an Alias.
568        """
569        if isinstance(self, Alias):
570            return self.this
571        return self

Returns the inner expression if this is an Alias.

def unnest_operands(self):
573    def unnest_operands(self):
574        """
575        Returns unnested operands as a tuple.
576        """
577        return tuple(arg.unnest() for arg in self.iter_expressions())

Returns unnested operands as a tuple.

def flatten(self, unnest=True):
579    def flatten(self, unnest=True):
580        """
581        Returns a generator which yields child nodes whose parents are the same class.
582
583        A AND B AND C -> [A, B, C]
584        """
585        for node in self.dfs(prune=lambda n: n.parent and type(n) is not self.__class__):
586            if type(node) is not self.__class__:
587                yield node.unnest() if unnest and not isinstance(node, Subquery) else node

Returns a generator which yields child nodes whose parents are the same class.

A AND B AND C -> [A, B, C]

def to_s(self) -> str:
595    def to_s(self) -> str:
596        """
597        Same as __repr__, but includes additional information which can be useful
598        for debugging, like empty or missing args and the AST nodes' object IDs.
599        """
600        return _to_s(self, verbose=True)

Same as __repr__, but includes additional information which can be useful for debugging, like empty or missing args and the AST nodes' object IDs.

def sql( self, dialect: Union[str, sqlglot.dialects.Dialect, Type[sqlglot.dialects.Dialect], NoneType] = None, **opts) -> str:
602    def sql(self, dialect: DialectType = None, **opts) -> str:
603        """
604        Returns SQL string representation of this tree.
605
606        Args:
607            dialect: the dialect of the output SQL string (eg. "spark", "hive", "presto", "mysql").
608            opts: other `sqlglot.generator.Generator` options.
609
610        Returns:
611            The SQL string.
612        """
613        from sqlglot.dialects import Dialect
614
615        return Dialect.get_or_raise(dialect).generate(self, **opts)

Returns SQL string representation of this tree.

Arguments:
  • dialect: the dialect of the output SQL string (eg. "spark", "hive", "presto", "mysql").
  • opts: other sqlglot.generator.Generator options.
Returns:

The SQL string.

def transform( self, fun: Callable, *args: Any, copy: bool = True, **kwargs) -> Expression:
617    def transform(self, fun: t.Callable, *args: t.Any, copy: bool = True, **kwargs) -> Expression:
618        """
619        Visits all tree nodes (excluding already transformed ones)
620        and applies the given transformation function to each node.
621
622        Args:
623            fun: a function which takes a node as an argument and returns a
624                new transformed node or the same node without modifications. If the function
625                returns None, then the corresponding node will be removed from the syntax tree.
626            copy: if set to True a new tree instance is constructed, otherwise the tree is
627                modified in place.
628
629        Returns:
630            The transformed tree.
631        """
632        root = None
633        new_node = None
634
635        for node in (self.copy() if copy else self).dfs(prune=lambda n: n is not new_node):
636            parent, arg_key, index = node.parent, node.arg_key, node.index
637            new_node = fun(node, *args, **kwargs)
638
639            if not root:
640                root = new_node
641            elif parent and arg_key and new_node is not node:
642                parent.set(arg_key, new_node, index)
643
644        assert root
645        return root.assert_is(Expression)

Visits all tree nodes (excluding already transformed ones) and applies the given transformation function to each node.

Arguments:
  • fun: a function which takes a node as an argument and returns a new transformed node or the same node without modifications. If the function returns None, then the corresponding node will be removed from the syntax tree.
  • copy: if set to True a new tree instance is constructed, otherwise the tree is modified in place.
Returns:

The transformed tree.

def replace(self, expression):
653    def replace(self, expression):
654        """
655        Swap out this expression with a new expression.
656
657        For example::
658
659            >>> tree = Select().select("x").from_("tbl")
660            >>> tree.find(Column).replace(column("y"))
661            Column(
662              this=Identifier(this=y, quoted=False))
663            >>> tree.sql()
664            'SELECT y FROM tbl'
665
666        Args:
667            expression: new node
668
669        Returns:
670            The new expression or expressions.
671        """
672        parent = self.parent
673
674        if not parent or parent is expression:
675            return expression
676
677        key = self.arg_key
678        value = parent.args.get(key)
679
680        if type(expression) is list and isinstance(value, Expression):
681            # We are trying to replace an Expression with a list, so it's assumed that
682            # the intention was to really replace the parent of this expression.
683            value.parent.replace(expression)
684        else:
685            parent.set(key, expression, self.index)
686
687        if expression is not self:
688            self.parent = None
689            self.arg_key = None
690            self.index = None
691
692        return expression

Swap out this expression with a new expression.

For example::

>>> tree = Select().select("x").from_("tbl")
>>> tree.find(Column).replace(column("y"))
Column(
  this=Identifier(this=y, quoted=False))
>>> tree.sql()
'SELECT y FROM tbl'
Arguments:
  • expression: new node
Returns:

The new expression or expressions.

def pop(self: ~E) -> ~E:
694    def pop(self: E) -> E:
695        """
696        Remove this expression from its AST.
697
698        Returns:
699            The popped expression.
700        """
701        self.replace(None)
702        return self

Remove this expression from its AST.

Returns:

The popped expression.

def assert_is(self, type_: Type[~E]) -> ~E:
704    def assert_is(self, type_: t.Type[E]) -> E:
705        """
706        Assert that this `Expression` is an instance of `type_`.
707
708        If it is NOT an instance of `type_`, this raises an assertion error.
709        Otherwise, this returns this expression.
710
711        Examples:
712            This is useful for type security in chained expressions:
713
714            >>> import sqlglot
715            >>> sqlglot.parse_one("SELECT x from y").assert_is(Select).select("z").sql()
716            'SELECT x, z FROM y'
717        """
718        if not isinstance(self, type_):
719            raise AssertionError(f"{self} is not {type_}.")
720        return self

Assert that this Expression is an instance of type_.

If it is NOT an instance of type_, this raises an assertion error. Otherwise, this returns this expression.

Examples:

This is useful for type security in chained expressions:

>>> import sqlglot
>>> sqlglot.parse_one("SELECT x from y").assert_is(Select).select("z").sql()
'SELECT x, z FROM y'
def error_messages(self, args: Optional[Sequence] = None) -> List[str]:
722    def error_messages(self, args: t.Optional[t.Sequence] = None) -> t.List[str]:
723        """
724        Checks if this expression is valid (e.g. all mandatory args are set).
725
726        Args:
727            args: a sequence of values that were used to instantiate a Func expression. This is used
728                to check that the provided arguments don't exceed the function argument limit.
729
730        Returns:
731            A list of error messages for all possible errors that were found.
732        """
733        errors: t.List[str] = []
734
735        for k in self.args:
736            if k not in self.arg_types:
737                errors.append(f"Unexpected keyword: '{k}' for {self.__class__}")
738        for k, mandatory in self.arg_types.items():
739            v = self.args.get(k)
740            if mandatory and (v is None or (isinstance(v, list) and not v)):
741                errors.append(f"Required keyword: '{k}' missing for {self.__class__}")
742
743        if (
744            args
745            and isinstance(self, Func)
746            and len(args) > len(self.arg_types)
747            and not self.is_var_len_args
748        ):
749            errors.append(
750                f"The number of provided arguments ({len(args)}) is greater than "
751                f"the maximum number of supported arguments ({len(self.arg_types)})"
752            )
753
754        return errors

Checks if this expression is valid (e.g. all mandatory args are set).

Arguments:
  • args: a sequence of values that were used to instantiate a Func expression. This is used to check that the provided arguments don't exceed the function argument limit.
Returns:

A list of error messages for all possible errors that were found.

def dump(self):
756    def dump(self):
757        """
758        Dump this Expression to a JSON-serializable dict.
759        """
760        from sqlglot.serde import dump
761
762        return dump(self)

Dump this Expression to a JSON-serializable dict.

@classmethod
def load(cls, obj):
764    @classmethod
765    def load(cls, obj):
766        """
767        Load a dict (as returned by `Expression.dump`) into an Expression instance.
768        """
769        from sqlglot.serde import load
770
771        return load(obj)

Load a dict (as returned by Expression.dump) into an Expression instance.

def and_( self, *expressions: Union[str, Expression, NoneType], dialect: Union[str, sqlglot.dialects.Dialect, Type[sqlglot.dialects.Dialect], NoneType] = None, copy: bool = True, wrap: bool = True, **opts) -> Condition:
773    def and_(
774        self,
775        *expressions: t.Optional[ExpOrStr],
776        dialect: DialectType = None,
777        copy: bool = True,
778        wrap: bool = True,
779        **opts,
780    ) -> Condition:
781        """
782        AND this condition with one or multiple expressions.
783
784        Example:
785            >>> condition("x=1").and_("y=1").sql()
786            'x = 1 AND y = 1'
787
788        Args:
789            *expressions: the SQL code strings to parse.
790                If an `Expression` instance is passed, it will be used as-is.
791            dialect: the dialect used to parse the input expression.
792            copy: whether to copy the involved expressions (only applies to Expressions).
793            wrap: whether to wrap the operands in `Paren`s. This is true by default to avoid
794                precedence issues, but can be turned off when the produced AST is too deep and
795                causes recursion-related issues.
796            opts: other options to use to parse the input expressions.
797
798        Returns:
799            The new And condition.
800        """
801        return and_(self, *expressions, dialect=dialect, copy=copy, wrap=wrap, **opts)

AND this condition with one or multiple expressions.

Example:
>>> condition("x=1").and_("y=1").sql()
'x = 1 AND y = 1'
Arguments:
  • *expressions: the SQL code strings to parse. If an Expression instance is passed, it will be used as-is.
  • dialect: the dialect used to parse the input expression.
  • copy: whether to copy the involved expressions (only applies to Expressions).
  • wrap: whether to wrap the operands in Parens. This is true by default to avoid precedence issues, but can be turned off when the produced AST is too deep and causes recursion-related issues.
  • opts: other options to use to parse the input expressions.
Returns:

The new And condition.

def or_( self, *expressions: Union[str, Expression, NoneType], dialect: Union[str, sqlglot.dialects.Dialect, Type[sqlglot.dialects.Dialect], NoneType] = None, copy: bool = True, wrap: bool = True, **opts) -> Condition:
803    def or_(
804        self,
805        *expressions: t.Optional[ExpOrStr],
806        dialect: DialectType = None,
807        copy: bool = True,
808        wrap: bool = True,
809        **opts,
810    ) -> Condition:
811        """
812        OR this condition with one or multiple expressions.
813
814        Example:
815            >>> condition("x=1").or_("y=1").sql()
816            'x = 1 OR y = 1'
817
818        Args:
819            *expressions: the SQL code strings to parse.
820                If an `Expression` instance is passed, it will be used as-is.
821            dialect: the dialect used to parse the input expression.
822            copy: whether to copy the involved expressions (only applies to Expressions).
823            wrap: whether to wrap the operands in `Paren`s. This is true by default to avoid
824                precedence issues, but can be turned off when the produced AST is too deep and
825                causes recursion-related issues.
826            opts: other options to use to parse the input expressions.
827
828        Returns:
829            The new Or condition.
830        """
831        return or_(self, *expressions, dialect=dialect, copy=copy, wrap=wrap, **opts)

OR this condition with one or multiple expressions.

Example:
>>> condition("x=1").or_("y=1").sql()
'x = 1 OR y = 1'
Arguments:
  • *expressions: the SQL code strings to parse. If an Expression instance is passed, it will be used as-is.
  • dialect: the dialect used to parse the input expression.
  • copy: whether to copy the involved expressions (only applies to Expressions).
  • wrap: whether to wrap the operands in Parens. This is true by default to avoid precedence issues, but can be turned off when the produced AST is too deep and causes recursion-related issues.
  • opts: other options to use to parse the input expressions.
Returns:

The new Or condition.

def not_(self, copy: bool = True):
833    def not_(self, copy: bool = True):
834        """
835        Wrap this condition with NOT.
836
837        Example:
838            >>> condition("x=1").not_().sql()
839            'NOT x = 1'
840
841        Args:
842            copy: whether to copy this object.
843
844        Returns:
845            The new Not instance.
846        """
847        return not_(self, copy=copy)

Wrap this condition with NOT.

Example:
>>> condition("x=1").not_().sql()
'NOT x = 1'
Arguments:
  • copy: whether to copy this object.
Returns:

The new Not instance.

def as_( self, alias: str | Identifier, quoted: Optional[bool] = None, dialect: Union[str, sqlglot.dialects.Dialect, Type[sqlglot.dialects.Dialect], NoneType] = None, copy: bool = True, **opts) -> Alias:
849    def as_(
850        self,
851        alias: str | Identifier,
852        quoted: t.Optional[bool] = None,
853        dialect: DialectType = None,
854        copy: bool = True,
855        **opts,
856    ) -> Alias:
857        return alias_(self, alias, quoted=quoted, dialect=dialect, copy=copy, **opts)
def isin( self, *expressions: Any, query: Union[str, Expression, NoneType] = None, unnest: Union[str, Expression, NoneType, Collection[Union[str, Expression]]] = None, copy: bool = True, **opts) -> In:
882    def isin(
883        self,
884        *expressions: t.Any,
885        query: t.Optional[ExpOrStr] = None,
886        unnest: t.Optional[ExpOrStr] | t.Collection[ExpOrStr] = None,
887        copy: bool = True,
888        **opts,
889    ) -> In:
890        subquery = maybe_parse(query, copy=copy, **opts) if query else None
891        if subquery and not isinstance(subquery, Subquery):
892            subquery = subquery.subquery(copy=False)
893
894        return In(
895            this=maybe_copy(self, copy),
896            expressions=[convert(e, copy=copy) for e in expressions],
897            query=subquery,
898            unnest=(
899                Unnest(
900                    expressions=[
901                        maybe_parse(t.cast(ExpOrStr, e), copy=copy, **opts)
902                        for e in ensure_list(unnest)
903                    ]
904                )
905                if unnest
906                else None
907            ),
908        )
def between( self, low: Any, high: Any, copy: bool = True, **opts) -> Between:
910    def between(self, low: t.Any, high: t.Any, copy: bool = True, **opts) -> Between:
911        return Between(
912            this=maybe_copy(self, copy),
913            low=convert(low, copy=copy, **opts),
914            high=convert(high, copy=copy, **opts),
915        )
def is_( self, other: Union[str, Expression]) -> Is:
917    def is_(self, other: ExpOrStr) -> Is:
918        return self._binop(Is, other)
def like( self, other: Union[str, Expression]) -> Like:
920    def like(self, other: ExpOrStr) -> Like:
921        return self._binop(Like, other)
def ilike( self, other: Union[str, Expression]) -> ILike:
923    def ilike(self, other: ExpOrStr) -> ILike:
924        return self._binop(ILike, other)
def eq(self, other: Any) -> EQ:
926    def eq(self, other: t.Any) -> EQ:
927        return self._binop(EQ, other)
def neq(self, other: Any) -> NEQ:
929    def neq(self, other: t.Any) -> NEQ:
930        return self._binop(NEQ, other)
def rlike( self, other: Union[str, Expression]) -> RegexpLike:
932    def rlike(self, other: ExpOrStr) -> RegexpLike:
933        return self._binop(RegexpLike, other)
def div( self, other: Union[str, Expression], typed: bool = False, safe: bool = False) -> Div:
935    def div(self, other: ExpOrStr, typed: bool = False, safe: bool = False) -> Div:
936        div = self._binop(Div, other)
937        div.args["typed"] = typed
938        div.args["safe"] = safe
939        return div
def asc(self, nulls_first: bool = True) -> Ordered:
941    def asc(self, nulls_first: bool = True) -> Ordered:
942        return Ordered(this=self.copy(), nulls_first=nulls_first)
def desc(self, nulls_first: bool = False) -> Ordered:
944    def desc(self, nulls_first: bool = False) -> Ordered:
945        return Ordered(this=self.copy(), desc=True, nulls_first=nulls_first)
IntoType = typing.Union[str, typing.Type[Expression], typing.Collection[typing.Union[str, typing.Type[Expression]]]]
ExpOrStr = typing.Union[str, Expression]
class Condition(Expression):
1028class Condition(Expression):
1029    """Logical conditions like x AND y, or simply x"""

Logical conditions like x AND y, or simply x

key = 'condition'
class Predicate(Condition):
1032class Predicate(Condition):
1033    """Relationships like x = y, x > 1, x >= y."""

Relationships like x = y, x > 1, x >= y.

key = 'predicate'
class DerivedTable(Expression):
1036class DerivedTable(Expression):
1037    @property
1038    def selects(self) -> t.List[Expression]:
1039        return self.this.selects if isinstance(self.this, Query) else []
1040
1041    @property
1042    def named_selects(self) -> t.List[str]:
1043        return [select.output_name for select in self.selects]
selects: List[Expression]
1037    @property
1038    def selects(self) -> t.List[Expression]:
1039        return self.this.selects if isinstance(self.this, Query) else []
named_selects: List[str]
1041    @property
1042    def named_selects(self) -> t.List[str]:
1043        return [select.output_name for select in self.selects]
key = 'derivedtable'
class Query(Expression):
1046class Query(Expression):
1047    def subquery(self, alias: t.Optional[ExpOrStr] = None, copy: bool = True) -> Subquery:
1048        """
1049        Returns a `Subquery` that wraps around this query.
1050
1051        Example:
1052            >>> subquery = Select().select("x").from_("tbl").subquery()
1053            >>> Select().select("x").from_(subquery).sql()
1054            'SELECT x FROM (SELECT x FROM tbl)'
1055
1056        Args:
1057            alias: an optional alias for the subquery.
1058            copy: if `False`, modify this expression instance in-place.
1059        """
1060        instance = maybe_copy(self, copy)
1061        if not isinstance(alias, Expression):
1062            alias = TableAlias(this=to_identifier(alias)) if alias else None
1063
1064        return Subquery(this=instance, alias=alias)
1065
1066    def limit(
1067        self: Q, expression: ExpOrStr | int, dialect: DialectType = None, copy: bool = True, **opts
1068    ) -> Q:
1069        """
1070        Adds a LIMIT clause to this query.
1071
1072        Example:
1073            >>> select("1").union(select("1")).limit(1).sql()
1074            'SELECT 1 UNION SELECT 1 LIMIT 1'
1075
1076        Args:
1077            expression: the SQL code string to parse.
1078                This can also be an integer.
1079                If a `Limit` instance is passed, it will be used as-is.
1080                If another `Expression` instance is passed, it will be wrapped in a `Limit`.
1081            dialect: the dialect used to parse the input expression.
1082            copy: if `False`, modify this expression instance in-place.
1083            opts: other options to use to parse the input expressions.
1084
1085        Returns:
1086            A limited Select expression.
1087        """
1088        return _apply_builder(
1089            expression=expression,
1090            instance=self,
1091            arg="limit",
1092            into=Limit,
1093            prefix="LIMIT",
1094            dialect=dialect,
1095            copy=copy,
1096            into_arg="expression",
1097            **opts,
1098        )
1099
1100    def offset(
1101        self: Q, expression: ExpOrStr | int, dialect: DialectType = None, copy: bool = True, **opts
1102    ) -> Q:
1103        """
1104        Set the OFFSET expression.
1105
1106        Example:
1107            >>> Select().from_("tbl").select("x").offset(10).sql()
1108            'SELECT x FROM tbl OFFSET 10'
1109
1110        Args:
1111            expression: the SQL code string to parse.
1112                This can also be an integer.
1113                If a `Offset` instance is passed, this is used as-is.
1114                If another `Expression` instance is passed, it will be wrapped in a `Offset`.
1115            dialect: the dialect used to parse the input expression.
1116            copy: if `False`, modify this expression instance in-place.
1117            opts: other options to use to parse the input expressions.
1118
1119        Returns:
1120            The modified Select expression.
1121        """
1122        return _apply_builder(
1123            expression=expression,
1124            instance=self,
1125            arg="offset",
1126            into=Offset,
1127            prefix="OFFSET",
1128            dialect=dialect,
1129            copy=copy,
1130            into_arg="expression",
1131            **opts,
1132        )
1133
1134    def order_by(
1135        self: Q,
1136        *expressions: t.Optional[ExpOrStr],
1137        append: bool = True,
1138        dialect: DialectType = None,
1139        copy: bool = True,
1140        **opts,
1141    ) -> Q:
1142        """
1143        Set the ORDER BY expression.
1144
1145        Example:
1146            >>> Select().from_("tbl").select("x").order_by("x DESC").sql()
1147            'SELECT x FROM tbl ORDER BY x DESC'
1148
1149        Args:
1150            *expressions: the SQL code strings to parse.
1151                If a `Group` instance is passed, this is used as-is.
1152                If another `Expression` instance is passed, it will be wrapped in a `Order`.
1153            append: if `True`, add to any existing expressions.
1154                Otherwise, this flattens all the `Order` expression into a single expression.
1155            dialect: the dialect used to parse the input expression.
1156            copy: if `False`, modify this expression instance in-place.
1157            opts: other options to use to parse the input expressions.
1158
1159        Returns:
1160            The modified Select expression.
1161        """
1162        return _apply_child_list_builder(
1163            *expressions,
1164            instance=self,
1165            arg="order",
1166            append=append,
1167            copy=copy,
1168            prefix="ORDER BY",
1169            into=Order,
1170            dialect=dialect,
1171            **opts,
1172        )
1173
1174    @property
1175    def ctes(self) -> t.List[CTE]:
1176        """Returns a list of all the CTEs attached to this query."""
1177        with_ = self.args.get("with")
1178        return with_.expressions if with_ else []
1179
1180    @property
1181    def selects(self) -> t.List[Expression]:
1182        """Returns the query's projections."""
1183        raise NotImplementedError("Query objects must implement `selects`")
1184
1185    @property
1186    def named_selects(self) -> t.List[str]:
1187        """Returns the output names of the query's projections."""
1188        raise NotImplementedError("Query objects must implement `named_selects`")
1189
1190    def select(
1191        self: Q,
1192        *expressions: t.Optional[ExpOrStr],
1193        append: bool = True,
1194        dialect: DialectType = None,
1195        copy: bool = True,
1196        **opts,
1197    ) -> Q:
1198        """
1199        Append to or set the SELECT expressions.
1200
1201        Example:
1202            >>> Select().select("x", "y").sql()
1203            'SELECT x, y'
1204
1205        Args:
1206            *expressions: the SQL code strings to parse.
1207                If an `Expression` instance is passed, it will be used as-is.
1208            append: if `True`, add to any existing expressions.
1209                Otherwise, this resets the expressions.
1210            dialect: the dialect used to parse the input expressions.
1211            copy: if `False`, modify this expression instance in-place.
1212            opts: other options to use to parse the input expressions.
1213
1214        Returns:
1215            The modified Query expression.
1216        """
1217        raise NotImplementedError("Query objects must implement `select`")
1218
1219    def with_(
1220        self: Q,
1221        alias: ExpOrStr,
1222        as_: ExpOrStr,
1223        recursive: t.Optional[bool] = None,
1224        materialized: t.Optional[bool] = None,
1225        append: bool = True,
1226        dialect: DialectType = None,
1227        copy: bool = True,
1228        scalar: bool = False,
1229        **opts,
1230    ) -> Q:
1231        """
1232        Append to or set the common table expressions.
1233
1234        Example:
1235            >>> Select().with_("tbl2", as_="SELECT * FROM tbl").select("x").from_("tbl2").sql()
1236            'WITH tbl2 AS (SELECT * FROM tbl) SELECT x FROM tbl2'
1237
1238        Args:
1239            alias: the SQL code string to parse as the table name.
1240                If an `Expression` instance is passed, this is used as-is.
1241            as_: the SQL code string to parse as the table expression.
1242                If an `Expression` instance is passed, it will be used as-is.
1243            recursive: set the RECURSIVE part of the expression. Defaults to `False`.
1244            materialized: set the MATERIALIZED part of the expression.
1245            append: if `True`, add to any existing expressions.
1246                Otherwise, this resets the expressions.
1247            dialect: the dialect used to parse the input expression.
1248            copy: if `False`, modify this expression instance in-place.
1249            scalar: if `True`, this is a scalar common table expression.
1250            opts: other options to use to parse the input expressions.
1251
1252        Returns:
1253            The modified expression.
1254        """
1255        return _apply_cte_builder(
1256            self,
1257            alias,
1258            as_,
1259            recursive=recursive,
1260            materialized=materialized,
1261            append=append,
1262            dialect=dialect,
1263            copy=copy,
1264            scalar=scalar,
1265            **opts,
1266        )
1267
1268    def union(
1269        self, *expressions: ExpOrStr, distinct: bool = True, dialect: DialectType = None, **opts
1270    ) -> Union:
1271        """
1272        Builds a UNION expression.
1273
1274        Example:
1275            >>> import sqlglot
1276            >>> sqlglot.parse_one("SELECT * FROM foo").union("SELECT * FROM bla").sql()
1277            'SELECT * FROM foo UNION SELECT * FROM bla'
1278
1279        Args:
1280            expressions: the SQL code strings.
1281                If `Expression` instances are passed, they will be used as-is.
1282            distinct: set the DISTINCT flag if and only if this is true.
1283            dialect: the dialect used to parse the input expression.
1284            opts: other options to use to parse the input expressions.
1285
1286        Returns:
1287            The new Union expression.
1288        """
1289        return union(self, *expressions, distinct=distinct, dialect=dialect, **opts)
1290
1291    def intersect(
1292        self, *expressions: ExpOrStr, distinct: bool = True, dialect: DialectType = None, **opts
1293    ) -> Intersect:
1294        """
1295        Builds an INTERSECT expression.
1296
1297        Example:
1298            >>> import sqlglot
1299            >>> sqlglot.parse_one("SELECT * FROM foo").intersect("SELECT * FROM bla").sql()
1300            'SELECT * FROM foo INTERSECT SELECT * FROM bla'
1301
1302        Args:
1303            expressions: the SQL code strings.
1304                If `Expression` instances are passed, they will be used as-is.
1305            distinct: set the DISTINCT flag if and only if this is true.
1306            dialect: the dialect used to parse the input expression.
1307            opts: other options to use to parse the input expressions.
1308
1309        Returns:
1310            The new Intersect expression.
1311        """
1312        return intersect(self, *expressions, distinct=distinct, dialect=dialect, **opts)
1313
1314    def except_(
1315        self, *expressions: ExpOrStr, distinct: bool = True, dialect: DialectType = None, **opts
1316    ) -> Except:
1317        """
1318        Builds an EXCEPT expression.
1319
1320        Example:
1321            >>> import sqlglot
1322            >>> sqlglot.parse_one("SELECT * FROM foo").except_("SELECT * FROM bla").sql()
1323            'SELECT * FROM foo EXCEPT SELECT * FROM bla'
1324
1325        Args:
1326            expressions: the SQL code strings.
1327                If `Expression` instance are passed, they will be used as-is.
1328            distinct: set the DISTINCT flag if and only if this is true.
1329            dialect: the dialect used to parse the input expression.
1330            opts: other options to use to parse the input expressions.
1331
1332        Returns:
1333            The new Except expression.
1334        """
1335        return except_(self, *expressions, distinct=distinct, dialect=dialect, **opts)
def subquery( self, alias: Union[str, Expression, NoneType] = None, copy: bool = True) -> Subquery:
1047    def subquery(self, alias: t.Optional[ExpOrStr] = None, copy: bool = True) -> Subquery:
1048        """
1049        Returns a `Subquery` that wraps around this query.
1050
1051        Example:
1052            >>> subquery = Select().select("x").from_("tbl").subquery()
1053            >>> Select().select("x").from_(subquery).sql()
1054            'SELECT x FROM (SELECT x FROM tbl)'
1055
1056        Args:
1057            alias: an optional alias for the subquery.
1058            copy: if `False`, modify this expression instance in-place.
1059        """
1060        instance = maybe_copy(self, copy)
1061        if not isinstance(alias, Expression):
1062            alias = TableAlias(this=to_identifier(alias)) if alias else None
1063
1064        return Subquery(this=instance, alias=alias)

Returns a Subquery that wraps around this query.

Example:
>>> subquery = Select().select("x").from_("tbl").subquery()
>>> Select().select("x").from_(subquery).sql()
'SELECT x FROM (SELECT x FROM tbl)'
Arguments:
  • alias: an optional alias for the subquery.
  • copy: if False, modify this expression instance in-place.
def limit( self: ~Q, expression: Union[str, Expression, int], dialect: Union[str, sqlglot.dialects.Dialect, Type[sqlglot.dialects.Dialect], NoneType] = None, copy: bool = True, **opts) -> ~Q:
1066    def limit(
1067        self: Q, expression: ExpOrStr | int, dialect: DialectType = None, copy: bool = True, **opts
1068    ) -> Q:
1069        """
1070        Adds a LIMIT clause to this query.
1071
1072        Example:
1073            >>> select("1").union(select("1")).limit(1).sql()
1074            'SELECT 1 UNION SELECT 1 LIMIT 1'
1075
1076        Args:
1077            expression: the SQL code string to parse.
1078                This can also be an integer.
1079                If a `Limit` instance is passed, it will be used as-is.
1080                If another `Expression` instance is passed, it will be wrapped in a `Limit`.
1081            dialect: the dialect used to parse the input expression.
1082            copy: if `False`, modify this expression instance in-place.
1083            opts: other options to use to parse the input expressions.
1084
1085        Returns:
1086            A limited Select expression.
1087        """
1088        return _apply_builder(
1089            expression=expression,
1090            instance=self,
1091            arg="limit",
1092            into=Limit,
1093            prefix="LIMIT",
1094            dialect=dialect,
1095            copy=copy,
1096            into_arg="expression",
1097            **opts,
1098        )

Adds a LIMIT clause to this query.

Example:
>>> select("1").union(select("1")).limit(1).sql()
'SELECT 1 UNION SELECT 1 LIMIT 1'
Arguments:
  • expression: the SQL code string to parse. This can also be an integer. If a Limit instance is passed, it will be used as-is. If another Expression instance is passed, it will be wrapped in a Limit.
  • dialect: the dialect used to parse the input expression.
  • copy: if False, modify this expression instance in-place.
  • opts: other options to use to parse the input expressions.
Returns:

A limited Select expression.

def offset( self: ~Q, expression: Union[str, Expression, int], dialect: Union[str, sqlglot.dialects.Dialect, Type[sqlglot.dialects.Dialect], NoneType] = None, copy: bool = True, **opts) -> ~Q:
1100    def offset(
1101        self: Q, expression: ExpOrStr | int, dialect: DialectType = None, copy: bool = True, **opts
1102    ) -> Q:
1103        """
1104        Set the OFFSET expression.
1105
1106        Example:
1107            >>> Select().from_("tbl").select("x").offset(10).sql()
1108            'SELECT x FROM tbl OFFSET 10'
1109
1110        Args:
1111            expression: the SQL code string to parse.
1112                This can also be an integer.
1113                If a `Offset` instance is passed, this is used as-is.
1114                If another `Expression` instance is passed, it will be wrapped in a `Offset`.
1115            dialect: the dialect used to parse the input expression.
1116            copy: if `False`, modify this expression instance in-place.
1117            opts: other options to use to parse the input expressions.
1118
1119        Returns:
1120            The modified Select expression.
1121        """
1122        return _apply_builder(
1123            expression=expression,
1124            instance=self,
1125            arg="offset",
1126            into=Offset,
1127            prefix="OFFSET",
1128            dialect=dialect,
1129            copy=copy,
1130            into_arg="expression",
1131            **opts,
1132        )

Set the OFFSET expression.

Example:
>>> Select().from_("tbl").select("x").offset(10).sql()
'SELECT x FROM tbl OFFSET 10'
Arguments:
  • expression: the SQL code string to parse. This can also be an integer. If a Offset instance is passed, this is used as-is. If another Expression instance is passed, it will be wrapped in a Offset.
  • dialect: the dialect used to parse the input expression.
  • copy: if False, modify this expression instance in-place.
  • opts: other options to use to parse the input expressions.
Returns:

The modified Select expression.

def order_by( self: ~Q, *expressions: Union[str, Expression, NoneType], append: bool = True, dialect: Union[str, sqlglot.dialects.Dialect, Type[sqlglot.dialects.Dialect], NoneType] = None, copy: bool = True, **opts) -> ~Q:
1134    def order_by(
1135        self: Q,
1136        *expressions: t.Optional[ExpOrStr],
1137        append: bool = True,
1138        dialect: DialectType = None,
1139        copy: bool = True,
1140        **opts,
1141    ) -> Q:
1142        """
1143        Set the ORDER BY expression.
1144
1145        Example:
1146            >>> Select().from_("tbl").select("x").order_by("x DESC").sql()
1147            'SELECT x FROM tbl ORDER BY x DESC'
1148
1149        Args:
1150            *expressions: the SQL code strings to parse.
1151                If a `Group` instance is passed, this is used as-is.
1152                If another `Expression` instance is passed, it will be wrapped in a `Order`.
1153            append: if `True`, add to any existing expressions.
1154                Otherwise, this flattens all the `Order` expression into a single expression.
1155            dialect: the dialect used to parse the input expression.
1156            copy: if `False`, modify this expression instance in-place.
1157            opts: other options to use to parse the input expressions.
1158
1159        Returns:
1160            The modified Select expression.
1161        """
1162        return _apply_child_list_builder(
1163            *expressions,
1164            instance=self,
1165            arg="order",
1166            append=append,
1167            copy=copy,
1168            prefix="ORDER BY",
1169            into=Order,
1170            dialect=dialect,
1171            **opts,
1172        )

Set the ORDER BY expression.

Example:
>>> Select().from_("tbl").select("x").order_by("x DESC").sql()
'SELECT x FROM tbl ORDER BY x DESC'
Arguments:
  • *expressions: the SQL code strings to parse. If a Group instance is passed, this is used as-is. If another Expression instance is passed, it will be wrapped in a Order.
  • append: if True, add to any existing expressions. Otherwise, this flattens all the Order expression into a single expression.
  • dialect: the dialect used to parse the input expression.
  • copy: if False, modify this expression instance in-place.
  • opts: other options to use to parse the input expressions.
Returns:

The modified Select expression.

ctes: List[CTE]
1174    @property
1175    def ctes(self) -> t.List[CTE]:
1176        """Returns a list of all the CTEs attached to this query."""
1177        with_ = self.args.get("with")
1178        return with_.expressions if with_ else []

Returns a list of all the CTEs attached to this query.

selects: List[Expression]
1180    @property
1181    def selects(self) -> t.List[Expression]:
1182        """Returns the query's projections."""
1183        raise NotImplementedError("Query objects must implement `selects`")

Returns the query's projections.

named_selects: List[str]
1185    @property
1186    def named_selects(self) -> t.List[str]:
1187        """Returns the output names of the query's projections."""
1188        raise NotImplementedError("Query objects must implement `named_selects`")

Returns the output names of the query's projections.

def select( self: ~Q, *expressions: Union[str, Expression, NoneType], append: bool = True, dialect: Union[str, sqlglot.dialects.Dialect, Type[sqlglot.dialects.Dialect], NoneType] = None, copy: bool = True, **opts) -> ~Q:
1190    def select(
1191        self: Q,
1192        *expressions: t.Optional[ExpOrStr],
1193        append: bool = True,
1194        dialect: DialectType = None,
1195        copy: bool = True,
1196        **opts,
1197    ) -> Q:
1198        """
1199        Append to or set the SELECT expressions.
1200
1201        Example:
1202            >>> Select().select("x", "y").sql()
1203            'SELECT x, y'
1204
1205        Args:
1206            *expressions: the SQL code strings to parse.
1207                If an `Expression` instance is passed, it will be used as-is.
1208            append: if `True`, add to any existing expressions.
1209                Otherwise, this resets the expressions.
1210            dialect: the dialect used to parse the input expressions.
1211            copy: if `False`, modify this expression instance in-place.
1212            opts: other options to use to parse the input expressions.
1213
1214        Returns:
1215            The modified Query expression.
1216        """
1217        raise NotImplementedError("Query objects must implement `select`")

Append to or set the SELECT expressions.

Example:
>>> Select().select("x", "y").sql()
'SELECT x, y'
Arguments:
  • *expressions: the SQL code strings to parse. If an Expression instance is passed, it will be used as-is.
  • append: if True, add to any existing expressions. Otherwise, this resets the expressions.
  • dialect: the dialect used to parse the input expressions.
  • copy: if False, modify this expression instance in-place.
  • opts: other options to use to parse the input expressions.
Returns:

The modified Query expression.

def with_( self: ~Q, alias: Union[str, Expression], as_: Union[str, Expression], recursive: Optional[bool] = None, materialized: Optional[bool] = None, append: bool = True, dialect: Union[str, sqlglot.dialects.Dialect, Type[sqlglot.dialects.Dialect], NoneType] = None, copy: bool = True, scalar: bool = False, **opts) -> ~Q:
1219    def with_(
1220        self: Q,
1221        alias: ExpOrStr,
1222        as_: ExpOrStr,
1223        recursive: t.Optional[bool] = None,
1224        materialized: t.Optional[bool] = None,
1225        append: bool = True,
1226        dialect: DialectType = None,
1227        copy: bool = True,
1228        scalar: bool = False,
1229        **opts,
1230    ) -> Q:
1231        """
1232        Append to or set the common table expressions.
1233
1234        Example:
1235            >>> Select().with_("tbl2", as_="SELECT * FROM tbl").select("x").from_("tbl2").sql()
1236            'WITH tbl2 AS (SELECT * FROM tbl) SELECT x FROM tbl2'
1237
1238        Args:
1239            alias: the SQL code string to parse as the table name.
1240                If an `Expression` instance is passed, this is used as-is.
1241            as_: the SQL code string to parse as the table expression.
1242                If an `Expression` instance is passed, it will be used as-is.
1243            recursive: set the RECURSIVE part of the expression. Defaults to `False`.
1244            materialized: set the MATERIALIZED part of the expression.
1245            append: if `True`, add to any existing expressions.
1246                Otherwise, this resets the expressions.
1247            dialect: the dialect used to parse the input expression.
1248            copy: if `False`, modify this expression instance in-place.
1249            scalar: if `True`, this is a scalar common table expression.
1250            opts: other options to use to parse the input expressions.
1251
1252        Returns:
1253            The modified expression.
1254        """
1255        return _apply_cte_builder(
1256            self,
1257            alias,
1258            as_,
1259            recursive=recursive,
1260            materialized=materialized,
1261            append=append,
1262            dialect=dialect,
1263            copy=copy,
1264            scalar=scalar,
1265            **opts,
1266        )

Append to or set the common table expressions.

Example:
>>> Select().with_("tbl2", as_="SELECT * FROM tbl").select("x").from_("tbl2").sql()
'WITH tbl2 AS (SELECT * FROM tbl) SELECT x FROM tbl2'
Arguments:
  • alias: the SQL code string to parse as the table name. If an Expression instance is passed, this is used as-is.
  • as_: the SQL code string to parse as the table expression. If an Expression instance is passed, it will be used as-is.
  • recursive: set the RECURSIVE part of the expression. Defaults to False.
  • materialized: set the MATERIALIZED part of the expression.
  • append: if True, add to any existing expressions. Otherwise, this resets the expressions.
  • dialect: the dialect used to parse the input expression.
  • copy: if False, modify this expression instance in-place.
  • scalar: if True, this is a scalar common table expression.
  • opts: other options to use to parse the input expressions.
Returns:

The modified expression.

def union( self, *expressions: Union[str, Expression], distinct: bool = True, dialect: Union[str, sqlglot.dialects.Dialect, Type[sqlglot.dialects.Dialect], NoneType] = None, **opts) -> Union:
1268    def union(
1269        self, *expressions: ExpOrStr, distinct: bool = True, dialect: DialectType = None, **opts
1270    ) -> Union:
1271        """
1272        Builds a UNION expression.
1273
1274        Example:
1275            >>> import sqlglot
1276            >>> sqlglot.parse_one("SELECT * FROM foo").union("SELECT * FROM bla").sql()
1277            'SELECT * FROM foo UNION SELECT * FROM bla'
1278
1279        Args:
1280            expressions: the SQL code strings.
1281                If `Expression` instances are passed, they will be used as-is.
1282            distinct: set the DISTINCT flag if and only if this is true.
1283            dialect: the dialect used to parse the input expression.
1284            opts: other options to use to parse the input expressions.
1285
1286        Returns:
1287            The new Union expression.
1288        """
1289        return union(self, *expressions, distinct=distinct, dialect=dialect, **opts)

Builds a UNION expression.

Example:
>>> import sqlglot
>>> sqlglot.parse_one("SELECT * FROM foo").union("SELECT * FROM bla").sql()
'SELECT * FROM foo UNION SELECT * FROM bla'
Arguments:
  • expressions: the SQL code strings. If Expression instances are passed, they will be used as-is.
  • distinct: set the DISTINCT flag if and only if this is true.
  • dialect: the dialect used to parse the input expression.
  • opts: other options to use to parse the input expressions.
Returns:

The new Union expression.

def intersect( self, *expressions: Union[str, Expression], distinct: bool = True, dialect: Union[str, sqlglot.dialects.Dialect, Type[sqlglot.dialects.Dialect], NoneType] = None, **opts) -> Intersect:
1291    def intersect(
1292        self, *expressions: ExpOrStr, distinct: bool = True, dialect: DialectType = None, **opts
1293    ) -> Intersect:
1294        """
1295        Builds an INTERSECT expression.
1296
1297        Example:
1298            >>> import sqlglot
1299            >>> sqlglot.parse_one("SELECT * FROM foo").intersect("SELECT * FROM bla").sql()
1300            'SELECT * FROM foo INTERSECT SELECT * FROM bla'
1301
1302        Args:
1303            expressions: the SQL code strings.
1304                If `Expression` instances are passed, they will be used as-is.
1305            distinct: set the DISTINCT flag if and only if this is true.
1306            dialect: the dialect used to parse the input expression.
1307            opts: other options to use to parse the input expressions.
1308
1309        Returns:
1310            The new Intersect expression.
1311        """
1312        return intersect(self, *expressions, distinct=distinct, dialect=dialect, **opts)

Builds an INTERSECT expression.

Example:
>>> import sqlglot
>>> sqlglot.parse_one("SELECT * FROM foo").intersect("SELECT * FROM bla").sql()
'SELECT * FROM foo INTERSECT SELECT * FROM bla'
Arguments:
  • expressions: the SQL code strings. If Expression instances are passed, they will be used as-is.
  • distinct: set the DISTINCT flag if and only if this is true.
  • dialect: the dialect used to parse the input expression.
  • opts: other options to use to parse the input expressions.
Returns:

The new Intersect expression.

def except_( self, *expressions: Union[str, Expression], distinct: bool = True, dialect: Union[str, sqlglot.dialects.Dialect, Type[sqlglot.dialects.Dialect], NoneType] = None, **opts) -> Except:
1314    def except_(
1315        self, *expressions: ExpOrStr, distinct: bool = True, dialect: DialectType = None, **opts
1316    ) -> Except:
1317        """
1318        Builds an EXCEPT expression.
1319
1320        Example:
1321            >>> import sqlglot
1322            >>> sqlglot.parse_one("SELECT * FROM foo").except_("SELECT * FROM bla").sql()
1323            'SELECT * FROM foo EXCEPT SELECT * FROM bla'
1324
1325        Args:
1326            expressions: the SQL code strings.
1327                If `Expression` instance are passed, they will be used as-is.
1328            distinct: set the DISTINCT flag if and only if this is true.
1329            dialect: the dialect used to parse the input expression.
1330            opts: other options to use to parse the input expressions.
1331
1332        Returns:
1333            The new Except expression.
1334        """
1335        return except_(self, *expressions, distinct=distinct, dialect=dialect, **opts)

Builds an EXCEPT expression.

Example:
>>> import sqlglot
>>> sqlglot.parse_one("SELECT * FROM foo").except_("SELECT * FROM bla").sql()
'SELECT * FROM foo EXCEPT SELECT * FROM bla'
Arguments:
  • expressions: the SQL code strings. If Expression instance are passed, they will be used as-is.
  • distinct: set the DISTINCT flag if and only if this is true.
  • dialect: the dialect used to parse the input expression.
  • opts: other options to use to parse the input expressions.
Returns:

The new Except expression.

key = 'query'
class UDTF(DerivedTable):
1338class UDTF(DerivedTable):
1339    @property
1340    def selects(self) -> t.List[Expression]:
1341        alias = self.args.get("alias")
1342        return alias.columns if alias else []
selects: List[Expression]
1339    @property
1340    def selects(self) -> t.List[Expression]:
1341        alias = self.args.get("alias")
1342        return alias.columns if alias else []
key = 'udtf'
class Cache(Expression):
1345class Cache(Expression):
1346    arg_types = {
1347        "this": True,
1348        "lazy": False,
1349        "options": False,
1350        "expression": False,
1351    }
arg_types = {'this': True, 'lazy': False, 'options': False, 'expression': False}
key = 'cache'
class Uncache(Expression):
1354class Uncache(Expression):
1355    arg_types = {"this": True, "exists": False}
arg_types = {'this': True, 'exists': False}
key = 'uncache'
class Refresh(Expression):
1358class Refresh(Expression):
1359    pass
key = 'refresh'
class DDL(Expression):
1362class DDL(Expression):
1363    @property
1364    def ctes(self) -> t.List[CTE]:
1365        """Returns a list of all the CTEs attached to this statement."""
1366        with_ = self.args.get("with")
1367        return with_.expressions if with_ else []
1368
1369    @property
1370    def selects(self) -> t.List[Expression]:
1371        """If this statement contains a query (e.g. a CTAS), this returns the query's projections."""
1372        return self.expression.selects if isinstance(self.expression, Query) else []
1373
1374    @property
1375    def named_selects(self) -> t.List[str]:
1376        """
1377        If this statement contains a query (e.g. a CTAS), this returns the output
1378        names of the query's projections.
1379        """
1380        return self.expression.named_selects if isinstance(self.expression, Query) else []
ctes: List[CTE]
1363    @property
1364    def ctes(self) -> t.List[CTE]:
1365        """Returns a list of all the CTEs attached to this statement."""
1366        with_ = self.args.get("with")
1367        return with_.expressions if with_ else []

Returns a list of all the CTEs attached to this statement.

selects: List[Expression]
1369    @property
1370    def selects(self) -> t.List[Expression]:
1371        """If this statement contains a query (e.g. a CTAS), this returns the query's projections."""
1372        return self.expression.selects if isinstance(self.expression, Query) else []

If this statement contains a query (e.g. a CTAS), this returns the query's projections.

named_selects: List[str]
1374    @property
1375    def named_selects(self) -> t.List[str]:
1376        """
1377        If this statement contains a query (e.g. a CTAS), this returns the output
1378        names of the query's projections.
1379        """
1380        return self.expression.named_selects if isinstance(self.expression, Query) else []

If this statement contains a query (e.g. a CTAS), this returns the output names of the query's projections.

key = 'ddl'
class DML(Expression):
1383class DML(Expression):
1384    def returning(
1385        self,
1386        expression: ExpOrStr,
1387        dialect: DialectType = None,
1388        copy: bool = True,
1389        **opts,
1390    ) -> "Self":
1391        """
1392        Set the RETURNING expression. Not supported by all dialects.
1393
1394        Example:
1395            >>> delete("tbl").returning("*", dialect="postgres").sql()
1396            'DELETE FROM tbl RETURNING *'
1397
1398        Args:
1399            expression: the SQL code strings to parse.
1400                If an `Expression` instance is passed, it will be used as-is.
1401            dialect: the dialect used to parse the input expressions.
1402            copy: if `False`, modify this expression instance in-place.
1403            opts: other options to use to parse the input expressions.
1404
1405        Returns:
1406            Delete: the modified expression.
1407        """
1408        return _apply_builder(
1409            expression=expression,
1410            instance=self,
1411            arg="returning",
1412            prefix="RETURNING",
1413            dialect=dialect,
1414            copy=copy,
1415            into=Returning,
1416            **opts,
1417        )
def returning( self, expression: Union[str, Expression], dialect: Union[str, sqlglot.dialects.Dialect, Type[sqlglot.dialects.Dialect], NoneType] = None, copy: bool = True, **opts) -> typing_extensions.Self:
1384    def returning(
1385        self,
1386        expression: ExpOrStr,
1387        dialect: DialectType = None,
1388        copy: bool = True,
1389        **opts,
1390    ) -> "Self":
1391        """
1392        Set the RETURNING expression. Not supported by all dialects.
1393
1394        Example:
1395            >>> delete("tbl").returning("*", dialect="postgres").sql()
1396            'DELETE FROM tbl RETURNING *'
1397
1398        Args:
1399            expression: the SQL code strings to parse.
1400                If an `Expression` instance is passed, it will be used as-is.
1401            dialect: the dialect used to parse the input expressions.
1402            copy: if `False`, modify this expression instance in-place.
1403            opts: other options to use to parse the input expressions.
1404
1405        Returns:
1406            Delete: the modified expression.
1407        """
1408        return _apply_builder(
1409            expression=expression,
1410            instance=self,
1411            arg="returning",
1412            prefix="RETURNING",
1413            dialect=dialect,
1414            copy=copy,
1415            into=Returning,
1416            **opts,
1417        )

Set the RETURNING expression. Not supported by all dialects.

Example:
>>> delete("tbl").returning("*", dialect="postgres").sql()
'DELETE FROM tbl RETURNING *'
Arguments:
  • expression: the SQL code strings to parse. If an Expression instance is passed, it will be used as-is.
  • dialect: the dialect used to parse the input expressions.
  • copy: if False, modify this expression instance in-place.
  • opts: other options to use to parse the input expressions.
Returns:

Delete: the modified expression.

key = 'dml'
class Create(DDL):
1420class Create(DDL):
1421    arg_types = {
1422        "with": False,
1423        "this": True,
1424        "kind": True,
1425        "expression": False,
1426        "exists": False,
1427        "properties": False,
1428        "replace": False,
1429        "refresh": False,
1430        "unique": False,
1431        "indexes": False,
1432        "no_schema_binding": False,
1433        "begin": False,
1434        "end": False,
1435        "clone": False,
1436        "concurrently": False,
1437        "clustered": False,
1438    }
1439
1440    @property
1441    def kind(self) -> t.Optional[str]:
1442        kind = self.args.get("kind")
1443        return kind and kind.upper()
arg_types = {'with': False, 'this': True, 'kind': True, 'expression': False, 'exists': False, 'properties': False, 'replace': False, 'refresh': False, 'unique': False, 'indexes': False, 'no_schema_binding': False, 'begin': False, 'end': False, 'clone': False, 'concurrently': False, 'clustered': False}
kind: Optional[str]
1440    @property
1441    def kind(self) -> t.Optional[str]:
1442        kind = self.args.get("kind")
1443        return kind and kind.upper()
key = 'create'
class SequenceProperties(Expression):
1446class SequenceProperties(Expression):
1447    arg_types = {
1448        "increment": False,
1449        "minvalue": False,
1450        "maxvalue": False,
1451        "cache": False,
1452        "start": False,
1453        "owned": False,
1454        "options": False,
1455    }
arg_types = {'increment': False, 'minvalue': False, 'maxvalue': False, 'cache': False, 'start': False, 'owned': False, 'options': False}
key = 'sequenceproperties'
class TruncateTable(Expression):
1458class TruncateTable(Expression):
1459    arg_types = {
1460        "expressions": True,
1461        "is_database": False,
1462        "exists": False,
1463        "only": False,
1464        "cluster": False,
1465        "identity": False,
1466        "option": False,
1467        "partition": False,
1468    }
arg_types = {'expressions': True, 'is_database': False, 'exists': False, 'only': False, 'cluster': False, 'identity': False, 'option': False, 'partition': False}
key = 'truncatetable'
class Clone(Expression):
1474class Clone(Expression):
1475    arg_types = {"this": True, "shallow": False, "copy": False}
arg_types = {'this': True, 'shallow': False, 'copy': False}
key = 'clone'
class Describe(Expression):
1478class Describe(Expression):
1479    arg_types = {
1480        "this": True,
1481        "style": False,
1482        "kind": False,
1483        "expressions": False,
1484        "partition": False,
1485        "format": False,
1486    }
arg_types = {'this': True, 'style': False, 'kind': False, 'expressions': False, 'partition': False, 'format': False}
key = 'describe'
class Attach(Expression):
1490class Attach(Expression):
1491    arg_types = {"this": True, "exists": False, "expressions": False}
arg_types = {'this': True, 'exists': False, 'expressions': False}
key = 'attach'
class Detach(Expression):
1495class Detach(Expression):
1496    arg_types = {"this": True, "exists": False}
arg_types = {'this': True, 'exists': False}
key = 'detach'
class Summarize(Expression):
1500class Summarize(Expression):
1501    arg_types = {"this": True, "table": False}
arg_types = {'this': True, 'table': False}
key = 'summarize'
class Kill(Expression):
1504class Kill(Expression):
1505    arg_types = {"this": True, "kind": False}
arg_types = {'this': True, 'kind': False}
key = 'kill'
class Pragma(Expression):
1508class Pragma(Expression):
1509    pass
key = 'pragma'
class Declare(Expression):
1512class Declare(Expression):
1513    arg_types = {"expressions": True}
arg_types = {'expressions': True}
key = 'declare'
class DeclareItem(Expression):
1516class DeclareItem(Expression):
1517    arg_types = {"this": True, "kind": True, "default": False}
arg_types = {'this': True, 'kind': True, 'default': False}
key = 'declareitem'
class Set(Expression):
1520class Set(Expression):
1521    arg_types = {"expressions": False, "unset": False, "tag": False}
arg_types = {'expressions': False, 'unset': False, 'tag': False}
key = 'set'
class Heredoc(Expression):
1524class Heredoc(Expression):
1525    arg_types = {"this": True, "tag": False}
arg_types = {'this': True, 'tag': False}
key = 'heredoc'
class SetItem(Expression):
1528class SetItem(Expression):
1529    arg_types = {
1530        "this": False,
1531        "expressions": False,
1532        "kind": False,
1533        "collate": False,  # MySQL SET NAMES statement
1534        "global": False,
1535    }
arg_types = {'this': False, 'expressions': False, 'kind': False, 'collate': False, 'global': False}
key = 'setitem'
class Show(Expression):
1538class Show(Expression):
1539    arg_types = {
1540        "this": True,
1541        "history": False,
1542        "terse": False,
1543        "target": False,
1544        "offset": False,
1545        "starts_with": False,
1546        "limit": False,
1547        "from": False,
1548        "like": False,
1549        "where": False,
1550        "db": False,
1551        "scope": False,
1552        "scope_kind": False,
1553        "full": False,
1554        "mutex": False,
1555        "query": False,
1556        "channel": False,
1557        "global": False,
1558        "log": False,
1559        "position": False,
1560        "types": False,
1561        "privileges": False,
1562    }
arg_types = {'this': True, 'history': False, 'terse': False, 'target': False, 'offset': False, 'starts_with': False, 'limit': False, 'from': False, 'like': False, 'where': False, 'db': False, 'scope': False, 'scope_kind': False, 'full': False, 'mutex': False, 'query': False, 'channel': False, 'global': False, 'log': False, 'position': False, 'types': False, 'privileges': False}
key = 'show'
class UserDefinedFunction(Expression):
1565class UserDefinedFunction(Expression):
1566    arg_types = {"this": True, "expressions": False, "wrapped": False}
arg_types = {'this': True, 'expressions': False, 'wrapped': False}
key = 'userdefinedfunction'
class CharacterSet(Expression):
1569class CharacterSet(Expression):
1570    arg_types = {"this": True, "default": False}
arg_types = {'this': True, 'default': False}
key = 'characterset'
class RecursiveWithSearch(Expression):
1573class RecursiveWithSearch(Expression):
1574    arg_types = {"kind": True, "this": True, "expression": True, "using": False}
arg_types = {'kind': True, 'this': True, 'expression': True, 'using': False}
key = 'recursivewithsearch'
class With(Expression):
1577class With(Expression):
1578    arg_types = {"expressions": True, "recursive": False, "search": False}
1579
1580    @property
1581    def recursive(self) -> bool:
1582        return bool(self.args.get("recursive"))
arg_types = {'expressions': True, 'recursive': False, 'search': False}
recursive: bool
1580    @property
1581    def recursive(self) -> bool:
1582        return bool(self.args.get("recursive"))
key = 'with'
class WithinGroup(Expression):
1585class WithinGroup(Expression):
1586    arg_types = {"this": True, "expression": False}
arg_types = {'this': True, 'expression': False}
key = 'withingroup'
class CTE(DerivedTable):
1591class CTE(DerivedTable):
1592    arg_types = {
1593        "this": True,
1594        "alias": True,
1595        "scalar": False,
1596        "materialized": False,
1597    }
arg_types = {'this': True, 'alias': True, 'scalar': False, 'materialized': False}
key = 'cte'
class ProjectionDef(Expression):
1600class ProjectionDef(Expression):
1601    arg_types = {"this": True, "expression": True}
arg_types = {'this': True, 'expression': True}
key = 'projectiondef'
class TableAlias(Expression):
1604class TableAlias(Expression):
1605    arg_types = {"this": False, "columns": False}
1606
1607    @property
1608    def columns(self):
1609        return self.args.get("columns") or []
arg_types = {'this': False, 'columns': False}
columns
1607    @property
1608    def columns(self):
1609        return self.args.get("columns") or []
key = 'tablealias'
class BitString(Condition):
1612class BitString(Condition):
1613    pass
key = 'bitstring'
class HexString(Condition):
1616class HexString(Condition):
1617    arg_types = {"this": True, "is_integer": False}
arg_types = {'this': True, 'is_integer': False}
key = 'hexstring'
class ByteString(Condition):
1620class ByteString(Condition):
1621    pass
key = 'bytestring'
class RawString(Condition):
1624class RawString(Condition):
1625    pass
key = 'rawstring'
class UnicodeString(Condition):
1628class UnicodeString(Condition):
1629    arg_types = {"this": True, "escape": False}
arg_types = {'this': True, 'escape': False}
key = 'unicodestring'
class Column(Condition):
1632class Column(Condition):
1633    arg_types = {"this": True, "table": False, "db": False, "catalog": False, "join_mark": False}
1634
1635    @property
1636    def table(self) -> str:
1637        return self.text("table")
1638
1639    @property
1640    def db(self) -> str:
1641        return self.text("db")
1642
1643    @property
1644    def catalog(self) -> str:
1645        return self.text("catalog")
1646
1647    @property
1648    def output_name(self) -> str:
1649        return self.name
1650
1651    @property
1652    def parts(self) -> t.List[Identifier]:
1653        """Return the parts of a column in order catalog, db, table, name."""
1654        return [
1655            t.cast(Identifier, self.args[part])
1656            for part in ("catalog", "db", "table", "this")
1657            if self.args.get(part)
1658        ]
1659
1660    def to_dot(self) -> Dot | Identifier:
1661        """Converts the column into a dot expression."""
1662        parts = self.parts
1663        parent = self.parent
1664
1665        while parent:
1666            if isinstance(parent, Dot):
1667                parts.append(parent.expression)
1668            parent = parent.parent
1669
1670        return Dot.build(deepcopy(parts)) if len(parts) > 1 else parts[0]
arg_types = {'this': True, 'table': False, 'db': False, 'catalog': False, 'join_mark': False}
table: str
1635    @property
1636    def table(self) -> str:
1637        return self.text("table")
db: str
1639    @property
1640    def db(self) -> str:
1641        return self.text("db")
catalog: str
1643    @property
1644    def catalog(self) -> str:
1645        return self.text("catalog")
output_name: str
1647    @property
1648    def output_name(self) -> str:
1649        return self.name

Name of the output column if this expression is a selection.

If the Expression has no output name, an empty string is returned.

Example:
>>> from sqlglot import parse_one
>>> parse_one("SELECT a")sqlglot.expressions[0].output_name
'a'
>>> parse_one("SELECT b AS c")sqlglot.expressions[0].output_name
'c'
>>> parse_one("SELECT 1 + 2")sqlglot.expressions[0].output_name
''
parts: List[Identifier]
1651    @property
1652    def parts(self) -> t.List[Identifier]:
1653        """Return the parts of a column in order catalog, db, table, name."""
1654        return [
1655            t.cast(Identifier, self.args[part])
1656            for part in ("catalog", "db", "table", "this")
1657            if self.args.get(part)
1658        ]

Return the parts of a column in order catalog, db, table, name.

def to_dot(self) -> Dot | Identifier:
1660    def to_dot(self) -> Dot | Identifier:
1661        """Converts the column into a dot expression."""
1662        parts = self.parts
1663        parent = self.parent
1664
1665        while parent:
1666            if isinstance(parent, Dot):
1667                parts.append(parent.expression)
1668            parent = parent.parent
1669
1670        return Dot.build(deepcopy(parts)) if len(parts) > 1 else parts[0]

Converts the column into a dot expression.

key = 'column'
class ColumnPosition(Expression):
1673class ColumnPosition(Expression):
1674    arg_types = {"this": False, "position": True}
arg_types = {'this': False, 'position': True}
key = 'columnposition'
class ColumnDef(Expression):
1677class ColumnDef(Expression):
1678    arg_types = {
1679        "this": True,
1680        "kind": False,
1681        "constraints": False,
1682        "exists": False,
1683        "position": False,
1684        "default": False,
1685        "output": False,
1686    }
1687
1688    @property
1689    def constraints(self) -> t.List[ColumnConstraint]:
1690        return self.args.get("constraints") or []
1691
1692    @property
1693    def kind(self) -> t.Optional[DataType]:
1694        return self.args.get("kind")
arg_types = {'this': True, 'kind': False, 'constraints': False, 'exists': False, 'position': False, 'default': False, 'output': False}
constraints: List[ColumnConstraint]
1688    @property
1689    def constraints(self) -> t.List[ColumnConstraint]:
1690        return self.args.get("constraints") or []
kind: Optional[DataType]
1692    @property
1693    def kind(self) -> t.Optional[DataType]:
1694        return self.args.get("kind")
key = 'columndef'
class AlterColumn(Expression):
1697class AlterColumn(Expression):
1698    arg_types = {
1699        "this": True,
1700        "dtype": False,
1701        "collate": False,
1702        "using": False,
1703        "default": False,
1704        "drop": False,
1705        "comment": False,
1706        "allow_null": False,
1707        "visible": False,
1708    }
arg_types = {'this': True, 'dtype': False, 'collate': False, 'using': False, 'default': False, 'drop': False, 'comment': False, 'allow_null': False, 'visible': False}
key = 'altercolumn'
class AlterIndex(Expression):
1712class AlterIndex(Expression):
1713    arg_types = {"this": True, "visible": True}
arg_types = {'this': True, 'visible': True}
key = 'alterindex'
class AlterDistStyle(Expression):
1717class AlterDistStyle(Expression):
1718    pass
key = 'alterdiststyle'
class AlterSortKey(Expression):
1721class AlterSortKey(Expression):
1722    arg_types = {"this": False, "expressions": False, "compound": False}
arg_types = {'this': False, 'expressions': False, 'compound': False}
key = 'altersortkey'
class AlterSet(Expression):
1725class AlterSet(Expression):
1726    arg_types = {
1727        "expressions": False,
1728        "option": False,
1729        "tablespace": False,
1730        "access_method": False,
1731        "file_format": False,
1732        "copy_options": False,
1733        "tag": False,
1734        "location": False,
1735        "serde": False,
1736    }
arg_types = {'expressions': False, 'option': False, 'tablespace': False, 'access_method': False, 'file_format': False, 'copy_options': False, 'tag': False, 'location': False, 'serde': False}
key = 'alterset'
class RenameColumn(Expression):
1739class RenameColumn(Expression):
1740    arg_types = {"this": True, "to": True, "exists": False}
arg_types = {'this': True, 'to': True, 'exists': False}
key = 'renamecolumn'
class AlterRename(Expression):
1743class AlterRename(Expression):
1744    pass
key = 'alterrename'
class SwapTable(Expression):
1747class SwapTable(Expression):
1748    pass
key = 'swaptable'
class Comment(Expression):
1751class Comment(Expression):
1752    arg_types = {
1753        "this": True,
1754        "kind": True,
1755        "expression": True,
1756        "exists": False,
1757        "materialized": False,
1758    }
arg_types = {'this': True, 'kind': True, 'expression': True, 'exists': False, 'materialized': False}
key = 'comment'
class Comprehension(Expression):
1761class Comprehension(Expression):
1762    arg_types = {"this": True, "expression": True, "iterator": True, "condition": False}
arg_types = {'this': True, 'expression': True, 'iterator': True, 'condition': False}
key = 'comprehension'
class MergeTreeTTLAction(Expression):
1766class MergeTreeTTLAction(Expression):
1767    arg_types = {
1768        "this": True,
1769        "delete": False,
1770        "recompress": False,
1771        "to_disk": False,
1772        "to_volume": False,
1773    }
arg_types = {'this': True, 'delete': False, 'recompress': False, 'to_disk': False, 'to_volume': False}
key = 'mergetreettlaction'
class MergeTreeTTL(Expression):
1777class MergeTreeTTL(Expression):
1778    arg_types = {
1779        "expressions": True,
1780        "where": False,
1781        "group": False,
1782        "aggregates": False,
1783    }
arg_types = {'expressions': True, 'where': False, 'group': False, 'aggregates': False}
key = 'mergetreettl'
class IndexConstraintOption(Expression):
1787class IndexConstraintOption(Expression):
1788    arg_types = {
1789        "key_block_size": False,
1790        "using": False,
1791        "parser": False,
1792        "comment": False,
1793        "visible": False,
1794        "engine_attr": False,
1795        "secondary_engine_attr": False,
1796    }
arg_types = {'key_block_size': False, 'using': False, 'parser': False, 'comment': False, 'visible': False, 'engine_attr': False, 'secondary_engine_attr': False}
key = 'indexconstraintoption'
class ColumnConstraint(Expression):
1799class ColumnConstraint(Expression):
1800    arg_types = {"this": False, "kind": True}
1801
1802    @property
1803    def kind(self) -> ColumnConstraintKind:
1804        return self.args["kind"]
arg_types = {'this': False, 'kind': True}
kind: ColumnConstraintKind
1802    @property
1803    def kind(self) -> ColumnConstraintKind:
1804        return self.args["kind"]
key = 'columnconstraint'
class ColumnConstraintKind(Expression):
1807class ColumnConstraintKind(Expression):
1808    pass
key = 'columnconstraintkind'
class AutoIncrementColumnConstraint(ColumnConstraintKind):
1811class AutoIncrementColumnConstraint(ColumnConstraintKind):
1812    pass
key = 'autoincrementcolumnconstraint'
class PeriodForSystemTimeConstraint(ColumnConstraintKind):
1815class PeriodForSystemTimeConstraint(ColumnConstraintKind):
1816    arg_types = {"this": True, "expression": True}
arg_types = {'this': True, 'expression': True}
key = 'periodforsystemtimeconstraint'
class CaseSpecificColumnConstraint(ColumnConstraintKind):
1819class CaseSpecificColumnConstraint(ColumnConstraintKind):
1820    arg_types = {"not_": True}
arg_types = {'not_': True}
key = 'casespecificcolumnconstraint'
class CharacterSetColumnConstraint(ColumnConstraintKind):
1823class CharacterSetColumnConstraint(ColumnConstraintKind):
1824    arg_types = {"this": True}
arg_types = {'this': True}
key = 'charactersetcolumnconstraint'
class CheckColumnConstraint(ColumnConstraintKind):
1827class CheckColumnConstraint(ColumnConstraintKind):
1828    arg_types = {"this": True, "enforced": False}
arg_types = {'this': True, 'enforced': False}
key = 'checkcolumnconstraint'
class ClusteredColumnConstraint(ColumnConstraintKind):
1831class ClusteredColumnConstraint(ColumnConstraintKind):
1832    pass
key = 'clusteredcolumnconstraint'
class CollateColumnConstraint(ColumnConstraintKind):
1835class CollateColumnConstraint(ColumnConstraintKind):
1836    pass
key = 'collatecolumnconstraint'
class CommentColumnConstraint(ColumnConstraintKind):
1839class CommentColumnConstraint(ColumnConstraintKind):
1840    pass
key = 'commentcolumnconstraint'
class CompressColumnConstraint(ColumnConstraintKind):
1843class CompressColumnConstraint(ColumnConstraintKind):
1844    arg_types = {"this": False}
arg_types = {'this': False}
key = 'compresscolumnconstraint'
class DateFormatColumnConstraint(ColumnConstraintKind):
1847class DateFormatColumnConstraint(ColumnConstraintKind):
1848    arg_types = {"this": True}
arg_types = {'this': True}
key = 'dateformatcolumnconstraint'
class DefaultColumnConstraint(ColumnConstraintKind):
1851class DefaultColumnConstraint(ColumnConstraintKind):
1852    pass
key = 'defaultcolumnconstraint'
class EncodeColumnConstraint(ColumnConstraintKind):
1855class EncodeColumnConstraint(ColumnConstraintKind):
1856    pass
key = 'encodecolumnconstraint'
class ExcludeColumnConstraint(ColumnConstraintKind):
1860class ExcludeColumnConstraint(ColumnConstraintKind):
1861    pass
key = 'excludecolumnconstraint'
class EphemeralColumnConstraint(ColumnConstraintKind):
1864class EphemeralColumnConstraint(ColumnConstraintKind):
1865    arg_types = {"this": False}
arg_types = {'this': False}
key = 'ephemeralcolumnconstraint'
class WithOperator(Expression):
1868class WithOperator(Expression):
1869    arg_types = {"this": True, "op": True}
arg_types = {'this': True, 'op': True}
key = 'withoperator'
class GeneratedAsIdentityColumnConstraint(ColumnConstraintKind):
1872class GeneratedAsIdentityColumnConstraint(ColumnConstraintKind):
1873    # this: True -> ALWAYS, this: False -> BY DEFAULT
1874    arg_types = {
1875        "this": False,
1876        "expression": False,
1877        "on_null": False,
1878        "start": False,
1879        "increment": False,
1880        "minvalue": False,
1881        "maxvalue": False,
1882        "cycle": False,
1883    }
arg_types = {'this': False, 'expression': False, 'on_null': False, 'start': False, 'increment': False, 'minvalue': False, 'maxvalue': False, 'cycle': False}
key = 'generatedasidentitycolumnconstraint'
class GeneratedAsRowColumnConstraint(ColumnConstraintKind):
1886class GeneratedAsRowColumnConstraint(ColumnConstraintKind):
1887    arg_types = {"start": False, "hidden": False}
arg_types = {'start': False, 'hidden': False}
key = 'generatedasrowcolumnconstraint'
class IndexColumnConstraint(ColumnConstraintKind):
1892class IndexColumnConstraint(ColumnConstraintKind):
1893    arg_types = {
1894        "this": False,
1895        "expressions": False,
1896        "kind": False,
1897        "index_type": False,
1898        "options": False,
1899        "expression": False,  # Clickhouse
1900        "granularity": False,
1901    }
arg_types = {'this': False, 'expressions': False, 'kind': False, 'index_type': False, 'options': False, 'expression': False, 'granularity': False}
key = 'indexcolumnconstraint'
class InlineLengthColumnConstraint(ColumnConstraintKind):
1904class InlineLengthColumnConstraint(ColumnConstraintKind):
1905    pass
key = 'inlinelengthcolumnconstraint'
class NonClusteredColumnConstraint(ColumnConstraintKind):
1908class NonClusteredColumnConstraint(ColumnConstraintKind):
1909    pass
key = 'nonclusteredcolumnconstraint'
class NotForReplicationColumnConstraint(ColumnConstraintKind):
1912class NotForReplicationColumnConstraint(ColumnConstraintKind):
1913    arg_types = {}
arg_types = {}
key = 'notforreplicationcolumnconstraint'
class MaskingPolicyColumnConstraint(ColumnConstraintKind):
1917class MaskingPolicyColumnConstraint(ColumnConstraintKind):
1918    arg_types = {"this": True, "expressions": False}
arg_types = {'this': True, 'expressions': False}
key = 'maskingpolicycolumnconstraint'
class NotNullColumnConstraint(ColumnConstraintKind):
1921class NotNullColumnConstraint(ColumnConstraintKind):
1922    arg_types = {"allow_null": False}
arg_types = {'allow_null': False}
key = 'notnullcolumnconstraint'
class OnUpdateColumnConstraint(ColumnConstraintKind):
1926class OnUpdateColumnConstraint(ColumnConstraintKind):
1927    pass
key = 'onupdatecolumnconstraint'
class TransformColumnConstraint(ColumnConstraintKind):
1931class TransformColumnConstraint(ColumnConstraintKind):
1932    pass
key = 'transformcolumnconstraint'
class PrimaryKeyColumnConstraint(ColumnConstraintKind):
1935class PrimaryKeyColumnConstraint(ColumnConstraintKind):
1936    arg_types = {"desc": False}
arg_types = {'desc': False}
key = 'primarykeycolumnconstraint'
class TitleColumnConstraint(ColumnConstraintKind):
1939class TitleColumnConstraint(ColumnConstraintKind):
1940    pass
key = 'titlecolumnconstraint'
class UniqueColumnConstraint(ColumnConstraintKind):
1943class UniqueColumnConstraint(ColumnConstraintKind):
1944    arg_types = {"this": False, "index_type": False, "on_conflict": False, "nulls": False}
arg_types = {'this': False, 'index_type': False, 'on_conflict': False, 'nulls': False}
key = 'uniquecolumnconstraint'
class UppercaseColumnConstraint(ColumnConstraintKind):
1947class UppercaseColumnConstraint(ColumnConstraintKind):
1948    arg_types: t.Dict[str, t.Any] = {}
arg_types: Dict[str, Any] = {}
key = 'uppercasecolumnconstraint'
class WatermarkColumnConstraint(Expression):
1952class WatermarkColumnConstraint(Expression):
1953    arg_types = {"this": True, "expression": True}
arg_types = {'this': True, 'expression': True}
key = 'watermarkcolumnconstraint'
class PathColumnConstraint(ColumnConstraintKind):
1956class PathColumnConstraint(ColumnConstraintKind):
1957    pass
key = 'pathcolumnconstraint'
class ProjectionPolicyColumnConstraint(ColumnConstraintKind):
1961class ProjectionPolicyColumnConstraint(ColumnConstraintKind):
1962    pass
key = 'projectionpolicycolumnconstraint'
class ComputedColumnConstraint(ColumnConstraintKind):
1967class ComputedColumnConstraint(ColumnConstraintKind):
1968    arg_types = {"this": True, "persisted": False, "not_null": False}
arg_types = {'this': True, 'persisted': False, 'not_null': False}
key = 'computedcolumnconstraint'
class Constraint(Expression):
1971class Constraint(Expression):
1972    arg_types = {"this": True, "expressions": True}
arg_types = {'this': True, 'expressions': True}
key = 'constraint'
class Delete(DML):
1975class Delete(DML):
1976    arg_types = {
1977        "with": False,
1978        "this": False,
1979        "using": False,
1980        "where": False,
1981        "returning": False,
1982        "limit": False,
1983        "tables": False,  # Multiple-Table Syntax (MySQL)
1984        "cluster": False,  # Clickhouse
1985    }
1986
1987    def delete(
1988        self,
1989        table: ExpOrStr,
1990        dialect: DialectType = None,
1991        copy: bool = True,
1992        **opts,
1993    ) -> Delete:
1994        """
1995        Create a DELETE expression or replace the table on an existing DELETE expression.
1996
1997        Example:
1998            >>> delete("tbl").sql()
1999            'DELETE FROM tbl'
2000
2001        Args:
2002            table: the table from which to delete.
2003            dialect: the dialect used to parse the input expression.
2004            copy: if `False`, modify this expression instance in-place.
2005            opts: other options to use to parse the input expressions.
2006
2007        Returns:
2008            Delete: the modified expression.
2009        """
2010        return _apply_builder(
2011            expression=table,
2012            instance=self,
2013            arg="this",
2014            dialect=dialect,
2015            into=Table,
2016            copy=copy,
2017            **opts,
2018        )
2019
2020    def where(
2021        self,
2022        *expressions: t.Optional[ExpOrStr],
2023        append: bool = True,
2024        dialect: DialectType = None,
2025        copy: bool = True,
2026        **opts,
2027    ) -> Delete:
2028        """
2029        Append to or set the WHERE expressions.
2030
2031        Example:
2032            >>> delete("tbl").where("x = 'a' OR x < 'b'").sql()
2033            "DELETE FROM tbl WHERE x = 'a' OR x < 'b'"
2034
2035        Args:
2036            *expressions: the SQL code strings to parse.
2037                If an `Expression` instance is passed, it will be used as-is.
2038                Multiple expressions are combined with an AND operator.
2039            append: if `True`, AND the new expressions to any existing expression.
2040                Otherwise, this resets the expression.
2041            dialect: the dialect used to parse the input expressions.
2042            copy: if `False`, modify this expression instance in-place.
2043            opts: other options to use to parse the input expressions.
2044
2045        Returns:
2046            Delete: the modified expression.
2047        """
2048        return _apply_conjunction_builder(
2049            *expressions,
2050            instance=self,
2051            arg="where",
2052            append=append,
2053            into=Where,
2054            dialect=dialect,
2055            copy=copy,
2056            **opts,
2057        )
arg_types = {'with': False, 'this': False, 'using': False, 'where': False, 'returning': False, 'limit': False, 'tables': False, 'cluster': False}
def delete( self, table: Union[str, Expression], dialect: Union[str, sqlglot.dialects.Dialect, Type[sqlglot.dialects.Dialect], NoneType] = None, copy: bool = True, **opts) -> Delete:
1987    def delete(
1988        self,
1989        table: ExpOrStr,
1990        dialect: DialectType = None,
1991        copy: bool = True,
1992        **opts,
1993    ) -> Delete:
1994        """
1995        Create a DELETE expression or replace the table on an existing DELETE expression.
1996
1997        Example:
1998            >>> delete("tbl").sql()
1999            'DELETE FROM tbl'
2000
2001        Args:
2002            table: the table from which to delete.
2003            dialect: the dialect used to parse the input expression.
2004            copy: if `False`, modify this expression instance in-place.
2005            opts: other options to use to parse the input expressions.
2006
2007        Returns:
2008            Delete: the modified expression.
2009        """
2010        return _apply_builder(
2011            expression=table,
2012            instance=self,
2013            arg="this",
2014            dialect=dialect,
2015            into=Table,
2016            copy=copy,
2017            **opts,
2018        )

Create a DELETE expression or replace the table on an existing DELETE expression.

Example:
>>> delete("tbl").sql()
'DELETE FROM tbl'
Arguments:
  • table: the table from which to delete.
  • dialect: the dialect used to parse the input expression.
  • copy: if False, modify this expression instance in-place.
  • opts: other options to use to parse the input expressions.
Returns:

Delete: the modified expression.

def where( self, *expressions: Union[str, Expression, NoneType], append: bool = True, dialect: Union[str, sqlglot.dialects.Dialect, Type[sqlglot.dialects.Dialect], NoneType] = None, copy: bool = True, **opts) -> Delete:
2020    def where(
2021        self,
2022        *expressions: t.Optional[ExpOrStr],
2023        append: bool = True,
2024        dialect: DialectType = None,
2025        copy: bool = True,
2026        **opts,
2027    ) -> Delete:
2028        """
2029        Append to or set the WHERE expressions.
2030
2031        Example:
2032            >>> delete("tbl").where("x = 'a' OR x < 'b'").sql()
2033            "DELETE FROM tbl WHERE x = 'a' OR x < 'b'"
2034
2035        Args:
2036            *expressions: the SQL code strings to parse.
2037                If an `Expression` instance is passed, it will be used as-is.
2038                Multiple expressions are combined with an AND operator.
2039            append: if `True`, AND the new expressions to any existing expression.
2040                Otherwise, this resets the expression.
2041            dialect: the dialect used to parse the input expressions.
2042            copy: if `False`, modify this expression instance in-place.
2043            opts: other options to use to parse the input expressions.
2044
2045        Returns:
2046            Delete: the modified expression.
2047        """
2048        return _apply_conjunction_builder(
2049            *expressions,
2050            instance=self,
2051            arg="where",
2052            append=append,
2053            into=Where,
2054            dialect=dialect,
2055            copy=copy,
2056            **opts,
2057        )

Append to or set the WHERE expressions.

Example:
>>> delete("tbl").where("x = 'a' OR x < 'b'").sql()
"DELETE FROM tbl WHERE x = 'a' OR x < 'b'"
Arguments:
  • *expressions: the SQL code strings to parse. If an Expression instance is passed, it will be used as-is. Multiple expressions are combined with an AND operator.
  • append: if True, AND the new expressions to any existing expression. Otherwise, this resets the expression.
  • dialect: the dialect used to parse the input expressions.
  • copy: if False, modify this expression instance in-place.
  • opts: other options to use to parse the input expressions.
Returns:

Delete: the modified expression.

key = 'delete'
class Drop(Expression):
2060class Drop(Expression):
2061    arg_types = {
2062        "this": False,
2063        "kind": False,
2064        "expressions": False,
2065        "exists": False,
2066        "temporary": False,
2067        "materialized": False,
2068        "cascade": False,
2069        "constraints": False,
2070        "purge": False,
2071        "cluster": False,
2072        "concurrently": False,
2073    }
2074
2075    @property
2076    def kind(self) -> t.Optional[str]:
2077        kind = self.args.get("kind")
2078        return kind and kind.upper()
arg_types = {'this': False, 'kind': False, 'expressions': False, 'exists': False, 'temporary': False, 'materialized': False, 'cascade': False, 'constraints': False, 'purge': False, 'cluster': False, 'concurrently': False}
kind: Optional[str]
2075    @property
2076    def kind(self) -> t.Optional[str]:
2077        kind = self.args.get("kind")
2078        return kind and kind.upper()
key = 'drop'
class Export(Expression):
2082class Export(Expression):
2083    arg_types = {"this": True, "connection": False, "options": True}
arg_types = {'this': True, 'connection': False, 'options': True}
key = 'export'
class Filter(Expression):
2086class Filter(Expression):
2087    arg_types = {"this": True, "expression": True}
arg_types = {'this': True, 'expression': True}
key = 'filter'
class Check(Expression):
2090class Check(Expression):
2091    pass
key = 'check'
class Changes(Expression):
2094class Changes(Expression):
2095    arg_types = {"information": True, "at_before": False, "end": False}
arg_types = {'information': True, 'at_before': False, 'end': False}
key = 'changes'
class Connect(Expression):
2099class Connect(Expression):
2100    arg_types = {"start": False, "connect": True, "nocycle": False}
arg_types = {'start': False, 'connect': True, 'nocycle': False}
key = 'connect'
class CopyParameter(Expression):
2103class CopyParameter(Expression):
2104    arg_types = {"this": True, "expression": False, "expressions": False}
arg_types = {'this': True, 'expression': False, 'expressions': False}
key = 'copyparameter'
class Copy(DML):
2107class Copy(DML):
2108    arg_types = {
2109        "this": True,
2110        "kind": True,
2111        "files": True,
2112        "credentials": False,
2113        "format": False,
2114        "params": False,
2115    }
arg_types = {'this': True, 'kind': True, 'files': True, 'credentials': False, 'format': False, 'params': False}
key = 'copy'
class Credentials(Expression):
2118class Credentials(Expression):
2119    arg_types = {
2120        "credentials": False,
2121        "encryption": False,
2122        "storage": False,
2123        "iam_role": False,
2124        "region": False,
2125    }
arg_types = {'credentials': False, 'encryption': False, 'storage': False, 'iam_role': False, 'region': False}
key = 'credentials'
class Prior(Expression):
2128class Prior(Expression):
2129    pass
key = 'prior'
class Directory(Expression):
2132class Directory(Expression):
2133    # https://spark.apache.org/docs/3.0.0-preview/sql-ref-syntax-dml-insert-overwrite-directory-hive.html
2134    arg_types = {"this": True, "local": False, "row_format": False}
arg_types = {'this': True, 'local': False, 'row_format': False}
key = 'directory'
class ForeignKey(Expression):
2137class ForeignKey(Expression):
2138    arg_types = {
2139        "expressions": False,
2140        "reference": False,
2141        "delete": False,
2142        "update": False,
2143    }
arg_types = {'expressions': False, 'reference': False, 'delete': False, 'update': False}
key = 'foreignkey'
class ColumnPrefix(Expression):
2146class ColumnPrefix(Expression):
2147    arg_types = {"this": True, "expression": True}
arg_types = {'this': True, 'expression': True}
key = 'columnprefix'
class PrimaryKey(Expression):
2150class PrimaryKey(Expression):
2151    arg_types = {"expressions": True, "options": False}
arg_types = {'expressions': True, 'options': False}
key = 'primarykey'
class Into(Expression):
2156class Into(Expression):
2157    arg_types = {
2158        "this": False,
2159        "temporary": False,
2160        "unlogged": False,
2161        "bulk_collect": False,
2162        "expressions": False,
2163    }
arg_types = {'this': False, 'temporary': False, 'unlogged': False, 'bulk_collect': False, 'expressions': False}
key = 'into'
class From(Expression):
2166class From(Expression):
2167    @property
2168    def name(self) -> str:
2169        return self.this.name
2170
2171    @property
2172    def alias_or_name(self) -> str:
2173        return self.this.alias_or_name
name: str
2167    @property
2168    def name(self) -> str:
2169        return self.this.name
alias_or_name: str
2171    @property
2172    def alias_or_name(self) -> str:
2173        return self.this.alias_or_name
key = 'from'
class Having(Expression):
2176class Having(Expression):
2177    pass
key = 'having'
class Hint(Expression):
2180class Hint(Expression):
2181    arg_types = {"expressions": True}
arg_types = {'expressions': True}
key = 'hint'
class JoinHint(Expression):
2184class JoinHint(Expression):
2185    arg_types = {"this": True, "expressions": True}
arg_types = {'this': True, 'expressions': True}
key = 'joinhint'
class Identifier(Expression):
2188class Identifier(Expression):
2189    arg_types = {"this": True, "quoted": False, "global": False, "temporary": False}
2190
2191    @property
2192    def quoted(self) -> bool:
2193        return bool(self.args.get("quoted"))
2194
2195    @property
2196    def hashable_args(self) -> t.Any:
2197        return (self.this, self.quoted)
2198
2199    @property
2200    def output_name(self) -> str:
2201        return self.name
arg_types = {'this': True, 'quoted': False, 'global': False, 'temporary': False}
quoted: bool
2191    @property
2192    def quoted(self) -> bool:
2193        return bool(self.args.get("quoted"))
hashable_args: Any
2195    @property
2196    def hashable_args(self) -> t.Any:
2197        return (self.this, self.quoted)
output_name: str
2199    @property
2200    def output_name(self) -> str:
2201        return self.name

Name of the output column if this expression is a selection.

If the Expression has no output name, an empty string is returned.

Example:
>>> from sqlglot import parse_one
>>> parse_one("SELECT a")sqlglot.expressions[0].output_name
'a'
>>> parse_one("SELECT b AS c")sqlglot.expressions[0].output_name
'c'
>>> parse_one("SELECT 1 + 2")sqlglot.expressions[0].output_name
''
key = 'identifier'
class Opclass(Expression):
2205class Opclass(Expression):
2206    arg_types = {"this": True, "expression": True}
arg_types = {'this': True, 'expression': True}
key = 'opclass'
class Index(Expression):
2209class Index(Expression):
2210    arg_types = {
2211        "this": False,
2212        "table": False,
2213        "unique": False,
2214        "primary": False,
2215        "amp": False,  # teradata
2216        "params": False,
2217    }
arg_types = {'this': False, 'table': False, 'unique': False, 'primary': False, 'amp': False, 'params': False}
key = 'index'
class IndexParameters(Expression):
2220class IndexParameters(Expression):
2221    arg_types = {
2222        "using": False,
2223        "include": False,
2224        "columns": False,
2225        "with_storage": False,
2226        "partition_by": False,
2227        "tablespace": False,
2228        "where": False,
2229        "on": False,
2230    }
arg_types = {'using': False, 'include': False, 'columns': False, 'with_storage': False, 'partition_by': False, 'tablespace': False, 'where': False, 'on': False}
key = 'indexparameters'
class Insert(DDL, DML):
2233class Insert(DDL, DML):
2234    arg_types = {
2235        "hint": False,
2236        "with": False,
2237        "is_function": False,
2238        "this": False,
2239        "expression": False,
2240        "conflict": False,
2241        "returning": False,
2242        "overwrite": False,
2243        "exists": False,
2244        "alternative": False,
2245        "where": False,
2246        "ignore": False,
2247        "by_name": False,
2248        "stored": False,
2249        "partition": False,
2250        "settings": False,
2251        "source": False,
2252    }
2253
2254    def with_(
2255        self,
2256        alias: ExpOrStr,
2257        as_: ExpOrStr,
2258        recursive: t.Optional[bool] = None,
2259        materialized: t.Optional[bool] = None,
2260        append: bool = True,
2261        dialect: DialectType = None,
2262        copy: bool = True,
2263        **opts,
2264    ) -> Insert:
2265        """
2266        Append to or set the common table expressions.
2267
2268        Example:
2269            >>> insert("SELECT x FROM cte", "t").with_("cte", as_="SELECT * FROM tbl").sql()
2270            'WITH cte AS (SELECT * FROM tbl) INSERT INTO t SELECT x FROM cte'
2271
2272        Args:
2273            alias: the SQL code string to parse as the table name.
2274                If an `Expression` instance is passed, this is used as-is.
2275            as_: the SQL code string to parse as the table expression.
2276                If an `Expression` instance is passed, it will be used as-is.
2277            recursive: set the RECURSIVE part of the expression. Defaults to `False`.
2278            materialized: set the MATERIALIZED part of the expression.
2279            append: if `True`, add to any existing expressions.
2280                Otherwise, this resets the expressions.
2281            dialect: the dialect used to parse the input expression.
2282            copy: if `False`, modify this expression instance in-place.
2283            opts: other options to use to parse the input expressions.
2284
2285        Returns:
2286            The modified expression.
2287        """
2288        return _apply_cte_builder(
2289            self,
2290            alias,
2291            as_,
2292            recursive=recursive,
2293            materialized=materialized,
2294            append=append,
2295            dialect=dialect,
2296            copy=copy,
2297            **opts,
2298        )
arg_types = {'hint': False, 'with': False, 'is_function': False, 'this': False, 'expression': False, 'conflict': False, 'returning': False, 'overwrite': False, 'exists': False, 'alternative': False, 'where': False, 'ignore': False, 'by_name': False, 'stored': False, 'partition': False, 'settings': False, 'source': False}
def with_( self, alias: Union[str, Expression], as_: Union[str, Expression], recursive: Optional[bool] = None, materialized: Optional[bool] = None, append: bool = True, dialect: Union[str, sqlglot.dialects.Dialect, Type[sqlglot.dialects.Dialect], NoneType] = None, copy: bool = True, **opts) -> Insert:
2254    def with_(
2255        self,
2256        alias: ExpOrStr,
2257        as_: ExpOrStr,
2258        recursive: t.Optional[bool] = None,
2259        materialized: t.Optional[bool] = None,
2260        append: bool = True,
2261        dialect: DialectType = None,
2262        copy: bool = True,
2263        **opts,
2264    ) -> Insert:
2265        """
2266        Append to or set the common table expressions.
2267
2268        Example:
2269            >>> insert("SELECT x FROM cte", "t").with_("cte", as_="SELECT * FROM tbl").sql()
2270            'WITH cte AS (SELECT * FROM tbl) INSERT INTO t SELECT x FROM cte'
2271
2272        Args:
2273            alias: the SQL code string to parse as the table name.
2274                If an `Expression` instance is passed, this is used as-is.
2275            as_: the SQL code string to parse as the table expression.
2276                If an `Expression` instance is passed, it will be used as-is.
2277            recursive: set the RECURSIVE part of the expression. Defaults to `False`.
2278            materialized: set the MATERIALIZED part of the expression.
2279            append: if `True`, add to any existing expressions.
2280                Otherwise, this resets the expressions.
2281            dialect: the dialect used to parse the input expression.
2282            copy: if `False`, modify this expression instance in-place.
2283            opts: other options to use to parse the input expressions.
2284
2285        Returns:
2286            The modified expression.
2287        """
2288        return _apply_cte_builder(
2289            self,
2290            alias,
2291            as_,
2292            recursive=recursive,
2293            materialized=materialized,
2294            append=append,
2295            dialect=dialect,
2296            copy=copy,
2297            **opts,
2298        )

Append to or set the common table expressions.

Example:
>>> insert("SELECT x FROM cte", "t").with_("cte", as_="SELECT * FROM tbl").sql()
'WITH cte AS (SELECT * FROM tbl) INSERT INTO t SELECT x FROM cte'
Arguments:
  • alias: the SQL code string to parse as the table name. If an Expression instance is passed, this is used as-is.
  • as_: the SQL code string to parse as the table expression. If an Expression instance is passed, it will be used as-is.
  • recursive: set the RECURSIVE part of the expression. Defaults to False.
  • materialized: set the MATERIALIZED part of the expression.
  • append: if True, add to any existing expressions. Otherwise, this resets the expressions.
  • dialect: the dialect used to parse the input expression.
  • copy: if False, modify this expression instance in-place.
  • opts: other options to use to parse the input expressions.
Returns:

The modified expression.

key = 'insert'
class ConditionalInsert(Expression):
2301class ConditionalInsert(Expression):
2302    arg_types = {"this": True, "expression": False, "else_": False}
arg_types = {'this': True, 'expression': False, 'else_': False}
key = 'conditionalinsert'
class MultitableInserts(Expression):
2305class MultitableInserts(Expression):
2306    arg_types = {"expressions": True, "kind": True, "source": True}
arg_types = {'expressions': True, 'kind': True, 'source': True}
key = 'multitableinserts'
class OnConflict(Expression):
2309class OnConflict(Expression):
2310    arg_types = {
2311        "duplicate": False,
2312        "expressions": False,
2313        "action": False,
2314        "conflict_keys": False,
2315        "constraint": False,
2316        "where": False,
2317    }
arg_types = {'duplicate': False, 'expressions': False, 'action': False, 'conflict_keys': False, 'constraint': False, 'where': False}
key = 'onconflict'
class OnCondition(Expression):
2320class OnCondition(Expression):
2321    arg_types = {"error": False, "empty": False, "null": False}
arg_types = {'error': False, 'empty': False, 'null': False}
key = 'oncondition'
class Returning(Expression):
2324class Returning(Expression):
2325    arg_types = {"expressions": True, "into": False}
arg_types = {'expressions': True, 'into': False}
key = 'returning'
class Introducer(Expression):
2329class Introducer(Expression):
2330    arg_types = {"this": True, "expression": True}
arg_types = {'this': True, 'expression': True}
key = 'introducer'
class National(Expression):
2334class National(Expression):
2335    pass
key = 'national'
class LoadData(Expression):
2338class LoadData(Expression):
2339    arg_types = {
2340        "this": True,
2341        "local": False,
2342        "overwrite": False,
2343        "inpath": True,
2344        "partition": False,
2345        "input_format": False,
2346        "serde": False,
2347    }
arg_types = {'this': True, 'local': False, 'overwrite': False, 'inpath': True, 'partition': False, 'input_format': False, 'serde': False}
key = 'loaddata'
class Partition(Expression):
2350class Partition(Expression):
2351    arg_types = {"expressions": True, "subpartition": False}
arg_types = {'expressions': True, 'subpartition': False}
key = 'partition'
class PartitionRange(Expression):
2354class PartitionRange(Expression):
2355    arg_types = {"this": True, "expression": True}
arg_types = {'this': True, 'expression': True}
key = 'partitionrange'
class PartitionId(Expression):
2359class PartitionId(Expression):
2360    pass
key = 'partitionid'
class Fetch(Expression):
2363class Fetch(Expression):
2364    arg_types = {
2365        "direction": False,
2366        "count": False,
2367        "limit_options": False,
2368    }
arg_types = {'direction': False, 'count': False, 'limit_options': False}
key = 'fetch'
class Grant(Expression):
2371class Grant(Expression):
2372    arg_types = {
2373        "privileges": True,
2374        "kind": False,
2375        "securable": True,
2376        "principals": True,
2377        "grant_option": False,
2378    }
arg_types = {'privileges': True, 'kind': False, 'securable': True, 'principals': True, 'grant_option': False}
key = 'grant'
class Group(Expression):
2381class Group(Expression):
2382    arg_types = {
2383        "expressions": False,
2384        "grouping_sets": False,
2385        "cube": False,
2386        "rollup": False,
2387        "totals": False,
2388        "all": False,
2389    }
arg_types = {'expressions': False, 'grouping_sets': False, 'cube': False, 'rollup': False, 'totals': False, 'all': False}
key = 'group'
class Cube(Expression):
2392class Cube(Expression):
2393    arg_types = {"expressions": False}
arg_types = {'expressions': False}
key = 'cube'
class Rollup(Expression):
2396class Rollup(Expression):
2397    arg_types = {"expressions": False}
arg_types = {'expressions': False}
key = 'rollup'
class GroupingSets(Expression):
2400class GroupingSets(Expression):
2401    arg_types = {"expressions": True}
arg_types = {'expressions': True}
key = 'groupingsets'
class Lambda(Expression):
2404class Lambda(Expression):
2405    arg_types = {"this": True, "expressions": True}
arg_types = {'this': True, 'expressions': True}
key = 'lambda'
class Limit(Expression):
2408class Limit(Expression):
2409    arg_types = {
2410        "this": False,
2411        "expression": True,
2412        "offset": False,
2413        "limit_options": False,
2414        "expressions": False,
2415    }
arg_types = {'this': False, 'expression': True, 'offset': False, 'limit_options': False, 'expressions': False}
key = 'limit'
class LimitOptions(Expression):
2418class LimitOptions(Expression):
2419    arg_types = {
2420        "percent": False,
2421        "rows": False,
2422        "with_ties": False,
2423    }
arg_types = {'percent': False, 'rows': False, 'with_ties': False}
key = 'limitoptions'
class Literal(Condition):
2426class Literal(Condition):
2427    arg_types = {"this": True, "is_string": True}
2428
2429    @property
2430    def hashable_args(self) -> t.Any:
2431        return (self.this, self.args.get("is_string"))
2432
2433    @classmethod
2434    def number(cls, number) -> Literal:
2435        return cls(this=str(number), is_string=False)
2436
2437    @classmethod
2438    def string(cls, string) -> Literal:
2439        return cls(this=str(string), is_string=True)
2440
2441    @property
2442    def output_name(self) -> str:
2443        return self.name
2444
2445    def to_py(self) -> int | str | Decimal:
2446        if self.is_number:
2447            try:
2448                return int(self.this)
2449            except ValueError:
2450                return Decimal(self.this)
2451        return self.this
arg_types = {'this': True, 'is_string': True}
hashable_args: Any
2429    @property
2430    def hashable_args(self) -> t.Any:
2431        return (self.this, self.args.get("is_string"))
@classmethod
def number(cls, number) -> Literal:
2433    @classmethod
2434    def number(cls, number) -> Literal:
2435        return cls(this=str(number), is_string=False)
@classmethod
def string(cls, string) -> Literal:
2437    @classmethod
2438    def string(cls, string) -> Literal:
2439        return cls(this=str(string), is_string=True)
output_name: str
2441    @property
2442    def output_name(self) -> str:
2443        return self.name

Name of the output column if this expression is a selection.

If the Expression has no output name, an empty string is returned.

Example:
>>> from sqlglot import parse_one
>>> parse_one("SELECT a")sqlglot.expressions[0].output_name
'a'
>>> parse_one("SELECT b AS c")sqlglot.expressions[0].output_name
'c'
>>> parse_one("SELECT 1 + 2")sqlglot.expressions[0].output_name
''
def to_py(self) -> int | str | decimal.Decimal:
2445    def to_py(self) -> int | str | Decimal:
2446        if self.is_number:
2447            try:
2448                return int(self.this)
2449            except ValueError:
2450                return Decimal(self.this)
2451        return self.this

Returns a Python object equivalent of the SQL node.

key = 'literal'
class Join(Expression):
2454class Join(Expression):
2455    arg_types = {
2456        "this": True,
2457        "on": False,
2458        "side": False,
2459        "kind": False,
2460        "using": False,
2461        "method": False,
2462        "global": False,
2463        "hint": False,
2464        "match_condition": False,  # Snowflake
2465        "expressions": False,
2466    }
2467
2468    @property
2469    def method(self) -> str:
2470        return self.text("method").upper()
2471
2472    @property
2473    def kind(self) -> str:
2474        return self.text("kind").upper()
2475
2476    @property
2477    def side(self) -> str:
2478        return self.text("side").upper()
2479
2480    @property
2481    def hint(self) -> str:
2482        return self.text("hint").upper()
2483
2484    @property
2485    def alias_or_name(self) -> str:
2486        return self.this.alias_or_name
2487
2488    @property
2489    def is_semi_or_anti_join(self) -> bool:
2490        return self.kind in ("SEMI", "ANTI")
2491
2492    def on(
2493        self,
2494        *expressions: t.Optional[ExpOrStr],
2495        append: bool = True,
2496        dialect: DialectType = None,
2497        copy: bool = True,
2498        **opts,
2499    ) -> Join:
2500        """
2501        Append to or set the ON expressions.
2502
2503        Example:
2504            >>> import sqlglot
2505            >>> sqlglot.parse_one("JOIN x", into=Join).on("y = 1").sql()
2506            'JOIN x ON y = 1'
2507
2508        Args:
2509            *expressions: the SQL code strings to parse.
2510                If an `Expression` instance is passed, it will be used as-is.
2511                Multiple expressions are combined with an AND operator.
2512            append: if `True`, AND the new expressions to any existing expression.
2513                Otherwise, this resets the expression.
2514            dialect: the dialect used to parse the input expressions.
2515            copy: if `False`, modify this expression instance in-place.
2516            opts: other options to use to parse the input expressions.
2517
2518        Returns:
2519            The modified Join expression.
2520        """
2521        join = _apply_conjunction_builder(
2522            *expressions,
2523            instance=self,
2524            arg="on",
2525            append=append,
2526            dialect=dialect,
2527            copy=copy,
2528            **opts,
2529        )
2530
2531        if join.kind == "CROSS":
2532            join.set("kind", None)
2533
2534        return join
2535
2536    def using(
2537        self,
2538        *expressions: t.Optional[ExpOrStr],
2539        append: bool = True,
2540        dialect: DialectType = None,
2541        copy: bool = True,
2542        **opts,
2543    ) -> Join:
2544        """
2545        Append to or set the USING expressions.
2546
2547        Example:
2548            >>> import sqlglot
2549            >>> sqlglot.parse_one("JOIN x", into=Join).using("foo", "bla").sql()
2550            'JOIN x USING (foo, bla)'
2551
2552        Args:
2553            *expressions: the SQL code strings to parse.
2554                If an `Expression` instance is passed, it will be used as-is.
2555            append: if `True`, concatenate the new expressions to the existing "using" list.
2556                Otherwise, this resets the expression.
2557            dialect: the dialect used to parse the input expressions.
2558            copy: if `False`, modify this expression instance in-place.
2559            opts: other options to use to parse the input expressions.
2560
2561        Returns:
2562            The modified Join expression.
2563        """
2564        join = _apply_list_builder(
2565            *expressions,
2566            instance=self,
2567            arg="using",
2568            append=append,
2569            dialect=dialect,
2570            copy=copy,
2571            **opts,
2572        )
2573
2574        if join.kind == "CROSS":
2575            join.set("kind", None)
2576
2577        return join
arg_types = {'this': True, 'on': False, 'side': False, 'kind': False, 'using': False, 'method': False, 'global': False, 'hint': False, 'match_condition': False, 'expressions': False}
method: str
2468    @property
2469    def method(self) -> str:
2470        return self.text("method").upper()
kind: str
2472    @property
2473    def kind(self) -> str:
2474        return self.text("kind").upper()
side: str
2476    @property
2477    def side(self) -> str:
2478        return self.text("side").upper()
hint: str
2480    @property
2481    def hint(self) -> str:
2482        return self.text("hint").upper()
alias_or_name: str
2484    @property
2485    def alias_or_name(self) -> str:
2486        return self.this.alias_or_name
is_semi_or_anti_join: bool
2488    @property
2489    def is_semi_or_anti_join(self) -> bool:
2490        return self.kind in ("SEMI", "ANTI")
def on( self, *expressions: Union[str, Expression, NoneType], append: bool = True, dialect: Union[str, sqlglot.dialects.Dialect, Type[sqlglot.dialects.Dialect], NoneType] = None, copy: bool = True, **opts) -> Join:
2492    def on(
2493        self,
2494        *expressions: t.Optional[ExpOrStr],
2495        append: bool = True,
2496        dialect: DialectType = None,
2497        copy: bool = True,
2498        **opts,
2499    ) -> Join:
2500        """
2501        Append to or set the ON expressions.
2502
2503        Example:
2504            >>> import sqlglot
2505            >>> sqlglot.parse_one("JOIN x", into=Join).on("y = 1").sql()
2506            'JOIN x ON y = 1'
2507
2508        Args:
2509            *expressions: the SQL code strings to parse.
2510                If an `Expression` instance is passed, it will be used as-is.
2511                Multiple expressions are combined with an AND operator.
2512            append: if `True`, AND the new expressions to any existing expression.
2513                Otherwise, this resets the expression.
2514            dialect: the dialect used to parse the input expressions.
2515            copy: if `False`, modify this expression instance in-place.
2516            opts: other options to use to parse the input expressions.
2517
2518        Returns:
2519            The modified Join expression.
2520        """
2521        join = _apply_conjunction_builder(
2522            *expressions,
2523            instance=self,
2524            arg="on",
2525            append=append,
2526            dialect=dialect,
2527            copy=copy,
2528            **opts,
2529        )
2530
2531        if join.kind == "CROSS":
2532            join.set("kind", None)
2533
2534        return join

Append to or set the ON expressions.

Example:
>>> import sqlglot
>>> sqlglot.parse_one("JOIN x", into=Join).on("y = 1").sql()
'JOIN x ON y = 1'
Arguments:
  • *expressions: the SQL code strings to parse. If an Expression instance is passed, it will be used as-is. Multiple expressions are combined with an AND operator.
  • append: if True, AND the new expressions to any existing expression. Otherwise, this resets the expression.
  • dialect: the dialect used to parse the input expressions.
  • copy: if False, modify this expression instance in-place.
  • opts: other options to use to parse the input expressions.
Returns:

The modified Join expression.

def using( self, *expressions: Union[str, Expression, NoneType], append: bool = True, dialect: Union[str, sqlglot.dialects.Dialect, Type[sqlglot.dialects.Dialect], NoneType] = None, copy: bool = True, **opts) -> Join:
2536    def using(
2537        self,
2538        *expressions: t.Optional[ExpOrStr],
2539        append: bool = True,
2540        dialect: DialectType = None,
2541        copy: bool = True,
2542        **opts,
2543    ) -> Join:
2544        """
2545        Append to or set the USING expressions.
2546
2547        Example:
2548            >>> import sqlglot
2549            >>> sqlglot.parse_one("JOIN x", into=Join).using("foo", "bla").sql()
2550            'JOIN x USING (foo, bla)'
2551
2552        Args:
2553            *expressions: the SQL code strings to parse.
2554                If an `Expression` instance is passed, it will be used as-is.
2555            append: if `True`, concatenate the new expressions to the existing "using" list.
2556                Otherwise, this resets the expression.
2557            dialect: the dialect used to parse the input expressions.
2558            copy: if `False`, modify this expression instance in-place.
2559            opts: other options to use to parse the input expressions.
2560
2561        Returns:
2562            The modified Join expression.
2563        """
2564        join = _apply_list_builder(
2565            *expressions,
2566            instance=self,
2567            arg="using",
2568            append=append,
2569            dialect=dialect,
2570            copy=copy,
2571            **opts,
2572        )
2573
2574        if join.kind == "CROSS":
2575            join.set("kind", None)
2576
2577        return join

Append to or set the USING expressions.

Example:
>>> import sqlglot
>>> sqlglot.parse_one("JOIN x", into=Join).using("foo", "bla").sql()
'JOIN x USING (foo, bla)'
Arguments:
  • *expressions: the SQL code strings to parse. If an Expression instance is passed, it will be used as-is.
  • append: if True, concatenate the new expressions to the existing "using" list. Otherwise, this resets the expression.
  • dialect: the dialect used to parse the input expressions.
  • copy: if False, modify this expression instance in-place.
  • opts: other options to use to parse the input expressions.
Returns:

The modified Join expression.

key = 'join'
class Lateral(UDTF):
2580class Lateral(UDTF):
2581    arg_types = {
2582        "this": True,
2583        "view": False,
2584        "outer": False,
2585        "alias": False,
2586        "cross_apply": False,  # True -> CROSS APPLY, False -> OUTER APPLY
2587    }
arg_types = {'this': True, 'view': False, 'outer': False, 'alias': False, 'cross_apply': False}
key = 'lateral'
class MatchRecognizeMeasure(Expression):
2590class MatchRecognizeMeasure(Expression):
2591    arg_types = {
2592        "this": True,
2593        "window_frame": False,
2594    }
arg_types = {'this': True, 'window_frame': False}
key = 'matchrecognizemeasure'
class MatchRecognize(Expression):
2597class MatchRecognize(Expression):
2598    arg_types = {
2599        "partition_by": False,
2600        "order": False,
2601        "measures": False,
2602        "rows": False,
2603        "after": False,
2604        "pattern": False,
2605        "define": False,
2606        "alias": False,
2607    }
arg_types = {'partition_by': False, 'order': False, 'measures': False, 'rows': False, 'after': False, 'pattern': False, 'define': False, 'alias': False}
key = 'matchrecognize'
class Final(Expression):
2612class Final(Expression):
2613    pass
key = 'final'
class Offset(Expression):
2616class Offset(Expression):
2617    arg_types = {"this": False, "expression": True, "expressions": False}
arg_types = {'this': False, 'expression': True, 'expressions': False}
key = 'offset'
class Order(Expression):
2620class Order(Expression):
2621    arg_types = {"this": False, "expressions": True, "siblings": False}
arg_types = {'this': False, 'expressions': True, 'siblings': False}
key = 'order'
class WithFill(Expression):
2625class WithFill(Expression):
2626    arg_types = {
2627        "from": False,
2628        "to": False,
2629        "step": False,
2630        "interpolate": False,
2631    }
arg_types = {'from': False, 'to': False, 'step': False, 'interpolate': False}
key = 'withfill'
class Cluster(Order):
2636class Cluster(Order):
2637    pass
key = 'cluster'
class Distribute(Order):
2640class Distribute(Order):
2641    pass
key = 'distribute'
class Sort(Order):
2644class Sort(Order):
2645    pass
key = 'sort'
class Ordered(Expression):
2648class Ordered(Expression):
2649    arg_types = {"this": True, "desc": False, "nulls_first": True, "with_fill": False}
arg_types = {'this': True, 'desc': False, 'nulls_first': True, 'with_fill': False}
key = 'ordered'
class Property(Expression):
2652class Property(Expression):
2653    arg_types = {"this": True, "value": True}
arg_types = {'this': True, 'value': True}
key = 'property'
class GrantPrivilege(Expression):
2656class GrantPrivilege(Expression):
2657    arg_types = {"this": True, "expressions": False}
arg_types = {'this': True, 'expressions': False}
key = 'grantprivilege'
class GrantPrincipal(Expression):
2660class GrantPrincipal(Expression):
2661    arg_types = {"this": True, "kind": False}
arg_types = {'this': True, 'kind': False}
key = 'grantprincipal'
class AllowedValuesProperty(Expression):
2664class AllowedValuesProperty(Expression):
2665    arg_types = {"expressions": True}
arg_types = {'expressions': True}
key = 'allowedvaluesproperty'
class AlgorithmProperty(Property):
2668class AlgorithmProperty(Property):
2669    arg_types = {"this": True}
arg_types = {'this': True}
key = 'algorithmproperty'
class AutoIncrementProperty(Property):
2672class AutoIncrementProperty(Property):
2673    arg_types = {"this": True}
arg_types = {'this': True}
key = 'autoincrementproperty'
class AutoRefreshProperty(Property):
2677class AutoRefreshProperty(Property):
2678    arg_types = {"this": True}
arg_types = {'this': True}
key = 'autorefreshproperty'
class BackupProperty(Property):
2681class BackupProperty(Property):
2682    arg_types = {"this": True}
arg_types = {'this': True}
key = 'backupproperty'
class BlockCompressionProperty(Property):
2685class BlockCompressionProperty(Property):
2686    arg_types = {
2687        "autotemp": False,
2688        "always": False,
2689        "default": False,
2690        "manual": False,
2691        "never": False,
2692    }
arg_types = {'autotemp': False, 'always': False, 'default': False, 'manual': False, 'never': False}
key = 'blockcompressionproperty'
class CharacterSetProperty(Property):
2695class CharacterSetProperty(Property):
2696    arg_types = {"this": True, "default": True}
arg_types = {'this': True, 'default': True}
key = 'charactersetproperty'
class ChecksumProperty(Property):
2699class ChecksumProperty(Property):
2700    arg_types = {"on": False, "default": False}
arg_types = {'on': False, 'default': False}
key = 'checksumproperty'
class CollateProperty(Property):
2703class CollateProperty(Property):
2704    arg_types = {"this": True, "default": False}
arg_types = {'this': True, 'default': False}
key = 'collateproperty'
class CopyGrantsProperty(Property):
2707class CopyGrantsProperty(Property):
2708    arg_types = {}
arg_types = {}
key = 'copygrantsproperty'
class DataBlocksizeProperty(Property):
2711class DataBlocksizeProperty(Property):
2712    arg_types = {
2713        "size": False,
2714        "units": False,
2715        "minimum": False,
2716        "maximum": False,
2717        "default": False,
2718    }
arg_types = {'size': False, 'units': False, 'minimum': False, 'maximum': False, 'default': False}
key = 'datablocksizeproperty'
class DataDeletionProperty(Property):
2721class DataDeletionProperty(Property):
2722    arg_types = {"on": True, "filter_col": False, "retention_period": False}
arg_types = {'on': True, 'filter_col': False, 'retention_period': False}
key = 'datadeletionproperty'
class DefinerProperty(Property):
2725class DefinerProperty(Property):
2726    arg_types = {"this": True}
arg_types = {'this': True}
key = 'definerproperty'
class DistKeyProperty(Property):
2729class DistKeyProperty(Property):
2730    arg_types = {"this": True}
arg_types = {'this': True}
key = 'distkeyproperty'
class DistributedByProperty(Property):
2735class DistributedByProperty(Property):
2736    arg_types = {"expressions": False, "kind": True, "buckets": False, "order": False}
arg_types = {'expressions': False, 'kind': True, 'buckets': False, 'order': False}
key = 'distributedbyproperty'
class DistStyleProperty(Property):
2739class DistStyleProperty(Property):
2740    arg_types = {"this": True}
arg_types = {'this': True}
key = 'diststyleproperty'
class DuplicateKeyProperty(Property):
2743class DuplicateKeyProperty(Property):
2744    arg_types = {"expressions": True}
arg_types = {'expressions': True}
key = 'duplicatekeyproperty'
class EngineProperty(Property):
2747class EngineProperty(Property):
2748    arg_types = {"this": True}
arg_types = {'this': True}
key = 'engineproperty'
class HeapProperty(Property):
2751class HeapProperty(Property):
2752    arg_types = {}
arg_types = {}
key = 'heapproperty'
class ToTableProperty(Property):
2755class ToTableProperty(Property):
2756    arg_types = {"this": True}
arg_types = {'this': True}
key = 'totableproperty'
class ExecuteAsProperty(Property):
2759class ExecuteAsProperty(Property):
2760    arg_types = {"this": True}
arg_types = {'this': True}
key = 'executeasproperty'
class ExternalProperty(Property):
2763class ExternalProperty(Property):
2764    arg_types = {"this": False}
arg_types = {'this': False}
key = 'externalproperty'
class FallbackProperty(Property):
2767class FallbackProperty(Property):
2768    arg_types = {"no": True, "protection": False}
arg_types = {'no': True, 'protection': False}
key = 'fallbackproperty'
class FileFormatProperty(Property):
2771class FileFormatProperty(Property):
2772    arg_types = {"this": True}
arg_types = {'this': True}
key = 'fileformatproperty'
class FreespaceProperty(Property):
2775class FreespaceProperty(Property):
2776    arg_types = {"this": True, "percent": False}
arg_types = {'this': True, 'percent': False}
key = 'freespaceproperty'
class GlobalProperty(Property):
2779class GlobalProperty(Property):
2780    arg_types = {}
arg_types = {}
key = 'globalproperty'
class IcebergProperty(Property):
2783class IcebergProperty(Property):
2784    arg_types = {}
arg_types = {}
key = 'icebergproperty'
class InheritsProperty(Property):
2787class InheritsProperty(Property):
2788    arg_types = {"expressions": True}
arg_types = {'expressions': True}
key = 'inheritsproperty'
class InputModelProperty(Property):
2791class InputModelProperty(Property):
2792    arg_types = {"this": True}
arg_types = {'this': True}
key = 'inputmodelproperty'
class OutputModelProperty(Property):
2795class OutputModelProperty(Property):
2796    arg_types = {"this": True}
arg_types = {'this': True}
key = 'outputmodelproperty'
class IsolatedLoadingProperty(Property):
2799class IsolatedLoadingProperty(Property):
2800    arg_types = {"no": False, "concurrent": False, "target": False}
arg_types = {'no': False, 'concurrent': False, 'target': False}
key = 'isolatedloadingproperty'
class JournalProperty(Property):
2803class JournalProperty(Property):
2804    arg_types = {
2805        "no": False,
2806        "dual": False,
2807        "before": False,
2808        "local": False,
2809        "after": False,
2810    }
arg_types = {'no': False, 'dual': False, 'before': False, 'local': False, 'after': False}
key = 'journalproperty'
class LanguageProperty(Property):
2813class LanguageProperty(Property):
2814    arg_types = {"this": True}
arg_types = {'this': True}
key = 'languageproperty'
class ClusteredByProperty(Property):
2818class ClusteredByProperty(Property):
2819    arg_types = {"expressions": True, "sorted_by": False, "buckets": True}
arg_types = {'expressions': True, 'sorted_by': False, 'buckets': True}
key = 'clusteredbyproperty'
class DictProperty(Property):
2822class DictProperty(Property):
2823    arg_types = {"this": True, "kind": True, "settings": False}
arg_types = {'this': True, 'kind': True, 'settings': False}
key = 'dictproperty'
class DictSubProperty(Property):
2826class DictSubProperty(Property):
2827    pass
key = 'dictsubproperty'
class DictRange(Property):
2830class DictRange(Property):
2831    arg_types = {"this": True, "min": True, "max": True}
arg_types = {'this': True, 'min': True, 'max': True}
key = 'dictrange'
class DynamicProperty(Property):
2834class DynamicProperty(Property):
2835    arg_types = {}
arg_types = {}
key = 'dynamicproperty'
class OnCluster(Property):
2840class OnCluster(Property):
2841    arg_types = {"this": True}
arg_types = {'this': True}
key = 'oncluster'
class EmptyProperty(Property):
2845class EmptyProperty(Property):
2846    arg_types = {}
arg_types = {}
key = 'emptyproperty'
class LikeProperty(Property):
2849class LikeProperty(Property):
2850    arg_types = {"this": True, "expressions": False}
arg_types = {'this': True, 'expressions': False}
key = 'likeproperty'
class LocationProperty(Property):
2853class LocationProperty(Property):
2854    arg_types = {"this": True}
arg_types = {'this': True}
key = 'locationproperty'
class LockProperty(Property):
2857class LockProperty(Property):
2858    arg_types = {"this": True}
arg_types = {'this': True}
key = 'lockproperty'
class LockingProperty(Property):
2861class LockingProperty(Property):
2862    arg_types = {
2863        "this": False,
2864        "kind": True,
2865        "for_or_in": False,
2866        "lock_type": True,
2867        "override": False,
2868    }
arg_types = {'this': False, 'kind': True, 'for_or_in': False, 'lock_type': True, 'override': False}
key = 'lockingproperty'
class LogProperty(Property):
2871class LogProperty(Property):
2872    arg_types = {"no": True}
arg_types = {'no': True}
key = 'logproperty'
class MaterializedProperty(Property):
2875class MaterializedProperty(Property):
2876    arg_types = {"this": False}
arg_types = {'this': False}
key = 'materializedproperty'
class MergeBlockRatioProperty(Property):
2879class MergeBlockRatioProperty(Property):
2880    arg_types = {"this": False, "no": False, "default": False, "percent": False}
arg_types = {'this': False, 'no': False, 'default': False, 'percent': False}
key = 'mergeblockratioproperty'
class NoPrimaryIndexProperty(Property):
2883class NoPrimaryIndexProperty(Property):
2884    arg_types = {}
arg_types = {}
key = 'noprimaryindexproperty'
class OnProperty(Property):
2887class OnProperty(Property):
2888    arg_types = {"this": True}
arg_types = {'this': True}
key = 'onproperty'
class OnCommitProperty(Property):
2891class OnCommitProperty(Property):
2892    arg_types = {"delete": False}
arg_types = {'delete': False}
key = 'oncommitproperty'
class PartitionedByProperty(Property):
2895class PartitionedByProperty(Property):
2896    arg_types = {"this": True}
arg_types = {'this': True}
key = 'partitionedbyproperty'
class PartitionByRangeProperty(Property):
2900class PartitionByRangeProperty(Property):
2901    arg_types = {"partition_expressions": True, "create_expressions": True}
arg_types = {'partition_expressions': True, 'create_expressions': True}
key = 'partitionbyrangeproperty'
class PartitionByRangePropertyDynamic(Expression):
2905class PartitionByRangePropertyDynamic(Expression):
2906    arg_types = {"this": False, "start": True, "end": True, "every": True}
arg_types = {'this': False, 'start': True, 'end': True, 'every': True}
key = 'partitionbyrangepropertydynamic'
class UniqueKeyProperty(Property):
2910class UniqueKeyProperty(Property):
2911    arg_types = {"expressions": True}
arg_types = {'expressions': True}
key = 'uniquekeyproperty'
class PartitionBoundSpec(Expression):
2915class PartitionBoundSpec(Expression):
2916    # this -> IN / MODULUS, expression -> REMAINDER, from_expressions -> FROM (...), to_expressions -> TO (...)
2917    arg_types = {
2918        "this": False,
2919        "expression": False,
2920        "from_expressions": False,
2921        "to_expressions": False,
2922    }
arg_types = {'this': False, 'expression': False, 'from_expressions': False, 'to_expressions': False}
key = 'partitionboundspec'
class PartitionedOfProperty(Property):
2925class PartitionedOfProperty(Property):
2926    # this -> parent_table (schema), expression -> FOR VALUES ... / DEFAULT
2927    arg_types = {"this": True, "expression": True}
arg_types = {'this': True, 'expression': True}
key = 'partitionedofproperty'
class StreamingTableProperty(Property):
2930class StreamingTableProperty(Property):
2931    arg_types = {}
arg_types = {}
key = 'streamingtableproperty'
class RemoteWithConnectionModelProperty(Property):
2934class RemoteWithConnectionModelProperty(Property):
2935    arg_types = {"this": True}
arg_types = {'this': True}
key = 'remotewithconnectionmodelproperty'
class ReturnsProperty(Property):
2938class ReturnsProperty(Property):
2939    arg_types = {"this": False, "is_table": False, "table": False, "null": False}
arg_types = {'this': False, 'is_table': False, 'table': False, 'null': False}
key = 'returnsproperty'
class StrictProperty(Property):
2942class StrictProperty(Property):
2943    arg_types = {}
arg_types = {}
key = 'strictproperty'
class RowFormatProperty(Property):
2946class RowFormatProperty(Property):
2947    arg_types = {"this": True}
arg_types = {'this': True}
key = 'rowformatproperty'
class RowFormatDelimitedProperty(Property):
2950class RowFormatDelimitedProperty(Property):
2951    # https://cwiki.apache.org/confluence/display/hive/languagemanual+dml
2952    arg_types = {
2953        "fields": False,
2954        "escaped": False,
2955        "collection_items": False,
2956        "map_keys": False,
2957        "lines": False,
2958        "null": False,
2959        "serde": False,
2960    }
arg_types = {'fields': False, 'escaped': False, 'collection_items': False, 'map_keys': False, 'lines': False, 'null': False, 'serde': False}
key = 'rowformatdelimitedproperty'
class RowFormatSerdeProperty(Property):
2963class RowFormatSerdeProperty(Property):
2964    arg_types = {"this": True, "serde_properties": False}
arg_types = {'this': True, 'serde_properties': False}
key = 'rowformatserdeproperty'
class QueryTransform(Expression):
2968class QueryTransform(Expression):
2969    arg_types = {
2970        "expressions": True,
2971        "command_script": True,
2972        "schema": False,
2973        "row_format_before": False,
2974        "record_writer": False,
2975        "row_format_after": False,
2976        "record_reader": False,
2977    }
arg_types = {'expressions': True, 'command_script': True, 'schema': False, 'row_format_before': False, 'record_writer': False, 'row_format_after': False, 'record_reader': False}
key = 'querytransform'
class SampleProperty(Property):
2980class SampleProperty(Property):
2981    arg_types = {"this": True}
arg_types = {'this': True}
key = 'sampleproperty'
class SecurityProperty(Property):
2985class SecurityProperty(Property):
2986    arg_types = {"this": True}
arg_types = {'this': True}
key = 'securityproperty'
class SchemaCommentProperty(Property):
2989class SchemaCommentProperty(Property):
2990    arg_types = {"this": True}
arg_types = {'this': True}
key = 'schemacommentproperty'
class SerdeProperties(Property):
2993class SerdeProperties(Property):
2994    arg_types = {"expressions": True, "with": False}
arg_types = {'expressions': True, 'with': False}
key = 'serdeproperties'
class SetProperty(Property):
2997class SetProperty(Property):
2998    arg_types = {"multi": True}
arg_types = {'multi': True}
key = 'setproperty'
class SharingProperty(Property):
3001class SharingProperty(Property):
3002    arg_types = {"this": False}
arg_types = {'this': False}
key = 'sharingproperty'
class SetConfigProperty(Property):
3005class SetConfigProperty(Property):
3006    arg_types = {"this": True}
arg_types = {'this': True}
key = 'setconfigproperty'
class SettingsProperty(Property):
3009class SettingsProperty(Property):
3010    arg_types = {"expressions": True}
arg_types = {'expressions': True}
key = 'settingsproperty'
class SortKeyProperty(Property):
3013class SortKeyProperty(Property):
3014    arg_types = {"this": True, "compound": False}
arg_types = {'this': True, 'compound': False}
key = 'sortkeyproperty'
class SqlReadWriteProperty(Property):
3017class SqlReadWriteProperty(Property):
3018    arg_types = {"this": True}
arg_types = {'this': True}
key = 'sqlreadwriteproperty'
class SqlSecurityProperty(Property):
3021class SqlSecurityProperty(Property):
3022    arg_types = {"definer": True}
arg_types = {'definer': True}
key = 'sqlsecurityproperty'
class StabilityProperty(Property):
3025class StabilityProperty(Property):
3026    arg_types = {"this": True}
arg_types = {'this': True}
key = 'stabilityproperty'
class StorageHandlerProperty(Property):
3029class StorageHandlerProperty(Property):
3030    arg_types = {"this": True}
arg_types = {'this': True}
key = 'storagehandlerproperty'
class TemporaryProperty(Property):
3033class TemporaryProperty(Property):
3034    arg_types = {"this": False}
arg_types = {'this': False}
key = 'temporaryproperty'
class SecureProperty(Property):
3037class SecureProperty(Property):
3038    arg_types = {}
arg_types = {}
key = 'secureproperty'
class Tags(ColumnConstraintKind, Property):
3042class Tags(ColumnConstraintKind, Property):
3043    arg_types = {"expressions": True}
arg_types = {'expressions': True}
key = 'tags'
class TransformModelProperty(Property):
3046class TransformModelProperty(Property):
3047    arg_types = {"expressions": True}
arg_types = {'expressions': True}
key = 'transformmodelproperty'
class TransientProperty(Property):
3050class TransientProperty(Property):
3051    arg_types = {"this": False}
arg_types = {'this': False}
key = 'transientproperty'
class UnloggedProperty(Property):
3054class UnloggedProperty(Property):
3055    arg_types = {}
arg_types = {}
key = 'unloggedproperty'
class ViewAttributeProperty(Property):
3059class ViewAttributeProperty(Property):
3060    arg_types = {"this": True}
arg_types = {'this': True}
key = 'viewattributeproperty'
class VolatileProperty(Property):
3063class VolatileProperty(Property):
3064    arg_types = {"this": False}
arg_types = {'this': False}
key = 'volatileproperty'
class WithDataProperty(Property):
3067class WithDataProperty(Property):
3068    arg_types = {"no": True, "statistics": False}
arg_types = {'no': True, 'statistics': False}
key = 'withdataproperty'
class WithJournalTableProperty(Property):
3071class WithJournalTableProperty(Property):
3072    arg_types = {"this": True}
arg_types = {'this': True}
key = 'withjournaltableproperty'
class WithSchemaBindingProperty(Property):
3075class WithSchemaBindingProperty(Property):
3076    arg_types = {"this": True}
arg_types = {'this': True}
key = 'withschemabindingproperty'
class WithSystemVersioningProperty(Property):
3079class WithSystemVersioningProperty(Property):
3080    arg_types = {
3081        "on": False,
3082        "this": False,
3083        "data_consistency": False,
3084        "retention_period": False,
3085        "with": True,
3086    }
arg_types = {'on': False, 'this': False, 'data_consistency': False, 'retention_period': False, 'with': True}
key = 'withsystemversioningproperty'
class WithProcedureOptions(Property):
3089class WithProcedureOptions(Property):
3090    arg_types = {"expressions": True}
arg_types = {'expressions': True}
key = 'withprocedureoptions'
class EncodeProperty(Property):
3093class EncodeProperty(Property):
3094    arg_types = {"this": True, "properties": False, "key": False}
arg_types = {'this': True, 'properties': False, 'key': False}
key = 'encodeproperty'
class IncludeProperty(Property):
3097class IncludeProperty(Property):
3098    arg_types = {"this": True, "alias": False, "column_def": False}
arg_types = {'this': True, 'alias': False, 'column_def': False}
key = 'includeproperty'
class ForceProperty(Property):
3101class ForceProperty(Property):
3102    arg_types = {}
arg_types = {}
key = 'forceproperty'
class Properties(Expression):
3105class Properties(Expression):
3106    arg_types = {"expressions": True}
3107
3108    NAME_TO_PROPERTY = {
3109        "ALGORITHM": AlgorithmProperty,
3110        "AUTO_INCREMENT": AutoIncrementProperty,
3111        "CHARACTER SET": CharacterSetProperty,
3112        "CLUSTERED_BY": ClusteredByProperty,
3113        "COLLATE": CollateProperty,
3114        "COMMENT": SchemaCommentProperty,
3115        "DEFINER": DefinerProperty,
3116        "DISTKEY": DistKeyProperty,
3117        "DISTRIBUTED_BY": DistributedByProperty,
3118        "DISTSTYLE": DistStyleProperty,
3119        "ENGINE": EngineProperty,
3120        "EXECUTE AS": ExecuteAsProperty,
3121        "FORMAT": FileFormatProperty,
3122        "LANGUAGE": LanguageProperty,
3123        "LOCATION": LocationProperty,
3124        "LOCK": LockProperty,
3125        "PARTITIONED_BY": PartitionedByProperty,
3126        "RETURNS": ReturnsProperty,
3127        "ROW_FORMAT": RowFormatProperty,
3128        "SORTKEY": SortKeyProperty,
3129        "ENCODE": EncodeProperty,
3130        "INCLUDE": IncludeProperty,
3131    }
3132
3133    PROPERTY_TO_NAME = {v: k for k, v in NAME_TO_PROPERTY.items()}
3134
3135    # CREATE property locations
3136    # Form: schema specified
3137    #   create [POST_CREATE]
3138    #     table a [POST_NAME]
3139    #     (b int) [POST_SCHEMA]
3140    #     with ([POST_WITH])
3141    #     index (b) [POST_INDEX]
3142    #
3143    # Form: alias selection
3144    #   create [POST_CREATE]
3145    #     table a [POST_NAME]
3146    #     as [POST_ALIAS] (select * from b) [POST_EXPRESSION]
3147    #     index (c) [POST_INDEX]
3148    class Location(AutoName):
3149        POST_CREATE = auto()
3150        POST_NAME = auto()
3151        POST_SCHEMA = auto()
3152        POST_WITH = auto()
3153        POST_ALIAS = auto()
3154        POST_EXPRESSION = auto()
3155        POST_INDEX = auto()
3156        UNSUPPORTED = auto()
3157
3158    @classmethod
3159    def from_dict(cls, properties_dict: t.Dict) -> Properties:
3160        expressions = []
3161        for key, value in properties_dict.items():
3162            property_cls = cls.NAME_TO_PROPERTY.get(key.upper())
3163            if property_cls:
3164                expressions.append(property_cls(this=convert(value)))
3165            else:
3166                expressions.append(Property(this=Literal.string(key), value=convert(value)))
3167
3168        return cls(expressions=expressions)
arg_types = {'expressions': True}
NAME_TO_PROPERTY = {'ALGORITHM': <class 'AlgorithmProperty'>, 'AUTO_INCREMENT': <class 'AutoIncrementProperty'>, 'CHARACTER SET': <class 'CharacterSetProperty'>, 'CLUSTERED_BY': <class 'ClusteredByProperty'>, 'COLLATE': <class 'CollateProperty'>, 'COMMENT': <class 'SchemaCommentProperty'>, 'DEFINER': <class 'DefinerProperty'>, 'DISTKEY': <class 'DistKeyProperty'>, 'DISTRIBUTED_BY': <class 'DistributedByProperty'>, 'DISTSTYLE': <class 'DistStyleProperty'>, 'ENGINE': <class 'EngineProperty'>, 'EXECUTE AS': <class 'ExecuteAsProperty'>, 'FORMAT': <class 'FileFormatProperty'>, 'LANGUAGE': <class 'LanguageProperty'>, 'LOCATION': <class 'LocationProperty'>, 'LOCK': <class 'LockProperty'>, 'PARTITIONED_BY': <class 'PartitionedByProperty'>, 'RETURNS': <class 'ReturnsProperty'>, 'ROW_FORMAT': <class 'RowFormatProperty'>, 'SORTKEY': <class 'SortKeyProperty'>, 'ENCODE': <class 'EncodeProperty'>, 'INCLUDE': <class 'IncludeProperty'>}
PROPERTY_TO_NAME = {<class 'AlgorithmProperty'>: 'ALGORITHM', <class 'AutoIncrementProperty'>: 'AUTO_INCREMENT', <class 'CharacterSetProperty'>: 'CHARACTER SET', <class 'ClusteredByProperty'>: 'CLUSTERED_BY', <class 'CollateProperty'>: 'COLLATE', <class 'SchemaCommentProperty'>: 'COMMENT', <class 'DefinerProperty'>: 'DEFINER', <class 'DistKeyProperty'>: 'DISTKEY', <class 'DistributedByProperty'>: 'DISTRIBUTED_BY', <class 'DistStyleProperty'>: 'DISTSTYLE', <class 'EngineProperty'>: 'ENGINE', <class 'ExecuteAsProperty'>: 'EXECUTE AS', <class 'FileFormatProperty'>: 'FORMAT', <class 'LanguageProperty'>: 'LANGUAGE', <class 'LocationProperty'>: 'LOCATION', <class 'LockProperty'>: 'LOCK', <class 'PartitionedByProperty'>: 'PARTITIONED_BY', <class 'ReturnsProperty'>: 'RETURNS', <class 'RowFormatProperty'>: 'ROW_FORMAT', <class 'SortKeyProperty'>: 'SORTKEY', <class 'EncodeProperty'>: 'ENCODE', <class 'IncludeProperty'>: 'INCLUDE'}
@classmethod
def from_dict(cls, properties_dict: Dict) -> Properties:
3158    @classmethod
3159    def from_dict(cls, properties_dict: t.Dict) -> Properties:
3160        expressions = []
3161        for key, value in properties_dict.items():
3162            property_cls = cls.NAME_TO_PROPERTY.get(key.upper())
3163            if property_cls:
3164                expressions.append(property_cls(this=convert(value)))
3165            else:
3166                expressions.append(Property(this=Literal.string(key), value=convert(value)))
3167
3168        return cls(expressions=expressions)
key = 'properties'
class Properties.Location(sqlglot.helper.AutoName):
3148    class Location(AutoName):
3149        POST_CREATE = auto()
3150        POST_NAME = auto()
3151        POST_SCHEMA = auto()
3152        POST_WITH = auto()
3153        POST_ALIAS = auto()
3154        POST_EXPRESSION = auto()
3155        POST_INDEX = auto()
3156        UNSUPPORTED = auto()

An enumeration.

POST_CREATE = <Location.POST_CREATE: 'POST_CREATE'>
POST_NAME = <Location.POST_NAME: 'POST_NAME'>
POST_SCHEMA = <Location.POST_SCHEMA: 'POST_SCHEMA'>
POST_WITH = <Location.POST_WITH: 'POST_WITH'>
POST_ALIAS = <Location.POST_ALIAS: 'POST_ALIAS'>
POST_EXPRESSION = <Location.POST_EXPRESSION: 'POST_EXPRESSION'>
POST_INDEX = <Location.POST_INDEX: 'POST_INDEX'>
UNSUPPORTED = <Location.UNSUPPORTED: 'UNSUPPORTED'>
class Qualify(Expression):
3171class Qualify(Expression):
3172    pass
key = 'qualify'
class InputOutputFormat(Expression):
3175class InputOutputFormat(Expression):
3176    arg_types = {"input_format": False, "output_format": False}
arg_types = {'input_format': False, 'output_format': False}
key = 'inputoutputformat'
class Return(Expression):
3180class Return(Expression):
3181    pass
key = 'return'
class Reference(Expression):
3184class Reference(Expression):
3185    arg_types = {"this": True, "expressions": False, "options": False}
arg_types = {'this': True, 'expressions': False, 'options': False}
key = 'reference'
class Tuple(Expression):
3188class Tuple(Expression):
3189    arg_types = {"expressions": False}
3190
3191    def isin(
3192        self,
3193        *expressions: t.Any,
3194        query: t.Optional[ExpOrStr] = None,
3195        unnest: t.Optional[ExpOrStr] | t.Collection[ExpOrStr] = None,
3196        copy: bool = True,
3197        **opts,
3198    ) -> In:
3199        return In(
3200            this=maybe_copy(self, copy),
3201            expressions=[convert(e, copy=copy) for e in expressions],
3202            query=maybe_parse(query, copy=copy, **opts) if query else None,
3203            unnest=(
3204                Unnest(
3205                    expressions=[
3206                        maybe_parse(t.cast(ExpOrStr, e), copy=copy, **opts)
3207                        for e in ensure_list(unnest)
3208                    ]
3209                )
3210                if unnest
3211                else None
3212            ),
3213        )
arg_types = {'expressions': False}
def isin( self, *expressions: Any, query: Union[str, Expression, NoneType] = None, unnest: Union[str, Expression, NoneType, Collection[Union[str, Expression]]] = None, copy: bool = True, **opts) -> In:
3191    def isin(
3192        self,
3193        *expressions: t.Any,
3194        query: t.Optional[ExpOrStr] = None,
3195        unnest: t.Optional[ExpOrStr] | t.Collection[ExpOrStr] = None,
3196        copy: bool = True,
3197        **opts,
3198    ) -> In:
3199        return In(
3200            this=maybe_copy(self, copy),
3201            expressions=[convert(e, copy=copy) for e in expressions],
3202            query=maybe_parse(query, copy=copy, **opts) if query else None,
3203            unnest=(
3204                Unnest(
3205                    expressions=[
3206                        maybe_parse(t.cast(ExpOrStr, e), copy=copy, **opts)
3207                        for e in ensure_list(unnest)
3208                    ]
3209                )
3210                if unnest
3211                else None
3212            ),
3213        )
key = 'tuple'
QUERY_MODIFIERS = {'match': False, 'laterals': False, 'joins': False, 'connect': False, 'pivots': False, 'prewhere': False, 'where': False, 'group': False, 'having': False, 'qualify': False, 'windows': False, 'distribute': False, 'sort': False, 'cluster': False, 'order': False, 'limit': False, 'offset': False, 'locks': False, 'sample': False, 'settings': False, 'format': False, 'options': False}
class QueryOption(Expression):
3244class QueryOption(Expression):
3245    arg_types = {"this": True, "expression": False}
arg_types = {'this': True, 'expression': False}
key = 'queryoption'
class WithTableHint(Expression):
3249class WithTableHint(Expression):
3250    arg_types = {"expressions": True}
arg_types = {'expressions': True}
key = 'withtablehint'
class IndexTableHint(Expression):
3254class IndexTableHint(Expression):
3255    arg_types = {"this": True, "expressions": False, "target": False}
arg_types = {'this': True, 'expressions': False, 'target': False}
key = 'indextablehint'
class HistoricalData(Expression):
3259class HistoricalData(Expression):
3260    arg_types = {"this": True, "kind": True, "expression": True}
arg_types = {'this': True, 'kind': True, 'expression': True}
key = 'historicaldata'
class Put(Expression):
3264class Put(Expression):
3265    arg_types = {"this": True, "target": True, "properties": False}
arg_types = {'this': True, 'target': True, 'properties': False}
key = 'put'
class Table(Expression):
3268class Table(Expression):
3269    arg_types = {
3270        "this": False,
3271        "alias": False,
3272        "db": False,
3273        "catalog": False,
3274        "laterals": False,
3275        "joins": False,
3276        "pivots": False,
3277        "hints": False,
3278        "system_time": False,
3279        "version": False,
3280        "format": False,
3281        "pattern": False,
3282        "ordinality": False,
3283        "when": False,
3284        "only": False,
3285        "partition": False,
3286        "changes": False,
3287        "rows_from": False,
3288        "sample": False,
3289    }
3290
3291    @property
3292    def name(self) -> str:
3293        if not self.this or isinstance(self.this, Func):
3294            return ""
3295        return self.this.name
3296
3297    @property
3298    def db(self) -> str:
3299        return self.text("db")
3300
3301    @property
3302    def catalog(self) -> str:
3303        return self.text("catalog")
3304
3305    @property
3306    def selects(self) -> t.List[Expression]:
3307        return []
3308
3309    @property
3310    def named_selects(self) -> t.List[str]:
3311        return []
3312
3313    @property
3314    def parts(self) -> t.List[Expression]:
3315        """Return the parts of a table in order catalog, db, table."""
3316        parts: t.List[Expression] = []
3317
3318        for arg in ("catalog", "db", "this"):
3319            part = self.args.get(arg)
3320
3321            if isinstance(part, Dot):
3322                parts.extend(part.flatten())
3323            elif isinstance(part, Expression):
3324                parts.append(part)
3325
3326        return parts
3327
3328    def to_column(self, copy: bool = True) -> Expression:
3329        parts = self.parts
3330        last_part = parts[-1]
3331
3332        if isinstance(last_part, Identifier):
3333            col: Expression = column(*reversed(parts[0:4]), fields=parts[4:], copy=copy)  # type: ignore
3334        else:
3335            # This branch will be reached if a function or array is wrapped in a `Table`
3336            col = last_part
3337
3338        alias = self.args.get("alias")
3339        if alias:
3340            col = alias_(col, alias.this, copy=copy)
3341
3342        return col
arg_types = {'this': False, 'alias': False, 'db': False, 'catalog': False, 'laterals': False, 'joins': False, 'pivots': False, 'hints': False, 'system_time': False, 'version': False, 'format': False, 'pattern': False, 'ordinality': False, 'when': False, 'only': False, 'partition': False, 'changes': False, 'rows_from': False, 'sample': False}
name: str
3291    @property
3292    def name(self) -> str:
3293        if not self.this or isinstance(self.this, Func):
3294            return ""
3295        return self.this.name
db: str
3297    @property
3298    def db(self) -> str:
3299        return self.text("db")
catalog: str
3301    @property
3302    def catalog(self) -> str:
3303        return self.text("catalog")
selects: List[Expression]
3305    @property
3306    def selects(self) -> t.List[Expression]:
3307        return []
named_selects: List[str]
3309    @property
3310    def named_selects(self) -> t.List[str]:
3311        return []
parts: List[Expression]
3313    @property
3314    def parts(self) -> t.List[Expression]:
3315        """Return the parts of a table in order catalog, db, table."""
3316        parts: t.List[Expression] = []
3317
3318        for arg in ("catalog", "db", "this"):
3319            part = self.args.get(arg)
3320
3321            if isinstance(part, Dot):
3322                parts.extend(part.flatten())
3323            elif isinstance(part, Expression):
3324                parts.append(part)
3325
3326        return parts

Return the parts of a table in order catalog, db, table.

def to_column(self, copy: bool = True) -> Expression:
3328    def to_column(self, copy: bool = True) -> Expression:
3329        parts = self.parts
3330        last_part = parts[-1]
3331
3332        if isinstance(last_part, Identifier):
3333            col: Expression = column(*reversed(parts[0:4]), fields=parts[4:], copy=copy)  # type: ignore
3334        else:
3335            # This branch will be reached if a function or array is wrapped in a `Table`
3336            col = last_part
3337
3338        alias = self.args.get("alias")
3339        if alias:
3340            col = alias_(col, alias.this, copy=copy)
3341
3342        return col
key = 'table'
class SetOperation(Query):
3345class SetOperation(Query):
3346    arg_types = {
3347        "with": False,
3348        "this": True,
3349        "expression": True,
3350        "distinct": False,
3351        "by_name": False,
3352        **QUERY_MODIFIERS,
3353    }
3354
3355    def select(
3356        self: S,
3357        *expressions: t.Optional[ExpOrStr],
3358        append: bool = True,
3359        dialect: DialectType = None,
3360        copy: bool = True,
3361        **opts,
3362    ) -> S:
3363        this = maybe_copy(self, copy)
3364        this.this.unnest().select(*expressions, append=append, dialect=dialect, copy=False, **opts)
3365        this.expression.unnest().select(
3366            *expressions, append=append, dialect=dialect, copy=False, **opts
3367        )
3368        return this
3369
3370    @property
3371    def named_selects(self) -> t.List[str]:
3372        return self.this.unnest().named_selects
3373
3374    @property
3375    def is_star(self) -> bool:
3376        return self.this.is_star or self.expression.is_star
3377
3378    @property
3379    def selects(self) -> t.List[Expression]:
3380        return self.this.unnest().selects
3381
3382    @property
3383    def left(self) -> Query:
3384        return self.this
3385
3386    @property
3387    def right(self) -> Query:
3388        return self.expression
arg_types = {'with': False, 'this': True, 'expression': True, 'distinct': False, 'by_name': False, 'match': False, 'laterals': False, 'joins': False, 'connect': False, 'pivots': False, 'prewhere': False, 'where': False, 'group': False, 'having': False, 'qualify': False, 'windows': False, 'distribute': False, 'sort': False, 'cluster': False, 'order': False, 'limit': False, 'offset': False, 'locks': False, 'sample': False, 'settings': False, 'format': False, 'options': False}
def select( self: ~S, *expressions: Union[str, Expression, NoneType], append: bool = True, dialect: Union[str, sqlglot.dialects.Dialect, Type[sqlglot.dialects.Dialect], NoneType] = None, copy: bool = True, **opts) -> ~S:
3355    def select(
3356        self: S,
3357        *expressions: t.Optional[ExpOrStr],
3358        append: bool = True,
3359        dialect: DialectType = None,
3360        copy: bool = True,
3361        **opts,
3362    ) -> S:
3363        this = maybe_copy(self, copy)
3364        this.this.unnest().select(*expressions, append=append, dialect=dialect, copy=False, **opts)
3365        this.expression.unnest().select(
3366            *expressions, append=append, dialect=dialect, copy=False, **opts
3367        )
3368        return this

Append to or set the SELECT expressions.

Example:
>>> Select().select("x", "y").sql()
'SELECT x, y'
Arguments:
  • *expressions: the SQL code strings to parse. If an Expression instance is passed, it will be used as-is.
  • append: if True, add to any existing expressions. Otherwise, this resets the expressions.
  • dialect: the dialect used to parse the input expressions.
  • copy: if False, modify this expression instance in-place.
  • opts: other options to use to parse the input expressions.
Returns:

The modified Query expression.

named_selects: List[str]
3370    @property
3371    def named_selects(self) -> t.List[str]:
3372        return self.this.unnest().named_selects

Returns the output names of the query's projections.

is_star: bool
3374    @property
3375    def is_star(self) -> bool:
3376        return self.this.is_star or self.expression.is_star

Checks whether an expression is a star.

selects: List[Expression]
3378    @property
3379    def selects(self) -> t.List[Expression]:
3380        return self.this.unnest().selects

Returns the query's projections.

left: Query
3382    @property
3383    def left(self) -> Query:
3384        return self.this
right: Query
3386    @property
3387    def right(self) -> Query:
3388        return self.expression
key = 'setoperation'
class Union(SetOperation):
3391class Union(SetOperation):
3392    pass
key = 'union'
class Except(SetOperation):
3395class Except(SetOperation):
3396    pass
key = 'except'
class Intersect(SetOperation):
3399class Intersect(SetOperation):
3400    pass
key = 'intersect'
class Update(DML):
3403class Update(DML):
3404    arg_types = {
3405        "with": False,
3406        "this": False,
3407        "expressions": True,
3408        "from": False,
3409        "where": False,
3410        "returning": False,
3411        "order": False,
3412        "limit": False,
3413    }
3414
3415    def table(
3416        self, expression: ExpOrStr, dialect: DialectType = None, copy: bool = True, **opts
3417    ) -> Update:
3418        """
3419        Set the table to update.
3420
3421        Example:
3422            >>> Update().table("my_table").set_("x = 1").sql()
3423            'UPDATE my_table SET x = 1'
3424
3425        Args:
3426            expression : the SQL code strings to parse.
3427                If a `Table` instance is passed, this is used as-is.
3428                If another `Expression` instance is passed, it will be wrapped in a `Table`.
3429            dialect: the dialect used to parse the input expression.
3430            copy: if `False`, modify this expression instance in-place.
3431            opts: other options to use to parse the input expressions.
3432
3433        Returns:
3434            The modified Update expression.
3435        """
3436        return _apply_builder(
3437            expression=expression,
3438            instance=self,
3439            arg="this",
3440            into=Table,
3441            prefix=None,
3442            dialect=dialect,
3443            copy=copy,
3444            **opts,
3445        )
3446
3447    def set_(
3448        self,
3449        *expressions: ExpOrStr,
3450        append: bool = True,
3451        dialect: DialectType = None,
3452        copy: bool = True,
3453        **opts,
3454    ) -> Update:
3455        """
3456        Append to or set the SET expressions.
3457
3458        Example:
3459            >>> Update().table("my_table").set_("x = 1").sql()
3460            'UPDATE my_table SET x = 1'
3461
3462        Args:
3463            *expressions: the SQL code strings to parse.
3464                If `Expression` instance(s) are passed, they will be used as-is.
3465                Multiple expressions are combined with a comma.
3466            append: if `True`, add the new expressions to any existing SET expressions.
3467                Otherwise, this resets the expressions.
3468            dialect: the dialect used to parse the input expressions.
3469            copy: if `False`, modify this expression instance in-place.
3470            opts: other options to use to parse the input expressions.
3471        """
3472        return _apply_list_builder(
3473            *expressions,
3474            instance=self,
3475            arg="expressions",
3476            append=append,
3477            into=Expression,
3478            prefix=None,
3479            dialect=dialect,
3480            copy=copy,
3481            **opts,
3482        )
3483
3484    def where(
3485        self,
3486        *expressions: t.Optional[ExpOrStr],
3487        append: bool = True,
3488        dialect: DialectType = None,
3489        copy: bool = True,
3490        **opts,
3491    ) -> Select:
3492        """
3493        Append to or set the WHERE expressions.
3494
3495        Example:
3496            >>> Update().table("tbl").set_("x = 1").where("x = 'a' OR x < 'b'").sql()
3497            "UPDATE tbl SET x = 1 WHERE x = 'a' OR x < 'b'"
3498
3499        Args:
3500            *expressions: the SQL code strings to parse.
3501                If an `Expression` instance is passed, it will be used as-is.
3502                Multiple expressions are combined with an AND operator.
3503            append: if `True`, AND the new expressions to any existing expression.
3504                Otherwise, this resets the expression.
3505            dialect: the dialect used to parse the input expressions.
3506            copy: if `False`, modify this expression instance in-place.
3507            opts: other options to use to parse the input expressions.
3508
3509        Returns:
3510            Select: the modified expression.
3511        """
3512        return _apply_conjunction_builder(
3513            *expressions,
3514            instance=self,
3515            arg="where",
3516            append=append,
3517            into=Where,
3518            dialect=dialect,
3519            copy=copy,
3520            **opts,
3521        )
3522
3523    def from_(
3524        self,
3525        expression: t.Optional[ExpOrStr] = None,
3526        dialect: DialectType = None,
3527        copy: bool = True,
3528        **opts,
3529    ) -> Update:
3530        """
3531        Set the FROM expression.
3532
3533        Example:
3534            >>> Update().table("my_table").set_("x = 1").from_("baz").sql()
3535            'UPDATE my_table SET x = 1 FROM baz'
3536
3537        Args:
3538            expression : the SQL code strings to parse.
3539                If a `From` instance is passed, this is used as-is.
3540                If another `Expression` instance is passed, it will be wrapped in a `From`.
3541                If nothing is passed in then a from is not applied to the expression
3542            dialect: the dialect used to parse the input expression.
3543            copy: if `False`, modify this expression instance in-place.
3544            opts: other options to use to parse the input expressions.
3545
3546        Returns:
3547            The modified Update expression.
3548        """
3549        if not expression:
3550            return maybe_copy(self, copy)
3551
3552        return _apply_builder(
3553            expression=expression,
3554            instance=self,
3555            arg="from",
3556            into=From,
3557            prefix="FROM",
3558            dialect=dialect,
3559            copy=copy,
3560            **opts,
3561        )
3562
3563    def with_(
3564        self,
3565        alias: ExpOrStr,
3566        as_: ExpOrStr,
3567        recursive: t.Optional[bool] = None,
3568        materialized: t.Optional[bool] = None,
3569        append: bool = True,
3570        dialect: DialectType = None,
3571        copy: bool = True,
3572        **opts,
3573    ) -> Update:
3574        """
3575        Append to or set the common table expressions.
3576
3577        Example:
3578            >>> Update().table("my_table").set_("x = 1").from_("baz").with_("baz", "SELECT id FROM foo").sql()
3579            'WITH baz AS (SELECT id FROM foo) UPDATE my_table SET x = 1 FROM baz'
3580
3581        Args:
3582            alias: the SQL code string to parse as the table name.
3583                If an `Expression` instance is passed, this is used as-is.
3584            as_: the SQL code string to parse as the table expression.
3585                If an `Expression` instance is passed, it will be used as-is.
3586            recursive: set the RECURSIVE part of the expression. Defaults to `False`.
3587            materialized: set the MATERIALIZED part of the expression.
3588            append: if `True`, add to any existing expressions.
3589                Otherwise, this resets the expressions.
3590            dialect: the dialect used to parse the input expression.
3591            copy: if `False`, modify this expression instance in-place.
3592            opts: other options to use to parse the input expressions.
3593
3594        Returns:
3595            The modified expression.
3596        """
3597        return _apply_cte_builder(
3598            self,
3599            alias,
3600            as_,
3601            recursive=recursive,
3602            materialized=materialized,
3603            append=append,
3604            dialect=dialect,
3605            copy=copy,
3606            **opts,
3607        )
arg_types = {'with': False, 'this': False, 'expressions': True, 'from': False, 'where': False, 'returning': False, 'order': False, 'limit': False}
def table( self, expression: Union[str, Expression], dialect: Union[str, sqlglot.dialects.Dialect, Type[sqlglot.dialects.Dialect], NoneType] = None, copy: bool = True, **opts) -> Update:
3415    def table(
3416        self, expression: ExpOrStr, dialect: DialectType = None, copy: bool = True, **opts
3417    ) -> Update:
3418        """
3419        Set the table to update.
3420
3421        Example:
3422            >>> Update().table("my_table").set_("x = 1").sql()
3423            'UPDATE my_table SET x = 1'
3424
3425        Args:
3426            expression : the SQL code strings to parse.
3427                If a `Table` instance is passed, this is used as-is.
3428                If another `Expression` instance is passed, it will be wrapped in a `Table`.
3429            dialect: the dialect used to parse the input expression.
3430            copy: if `False`, modify this expression instance in-place.
3431            opts: other options to use to parse the input expressions.
3432
3433        Returns:
3434            The modified Update expression.
3435        """
3436        return _apply_builder(
3437            expression=expression,
3438            instance=self,
3439            arg="this",
3440            into=Table,
3441            prefix=None,
3442            dialect=dialect,
3443            copy=copy,
3444            **opts,
3445        )

Set the table to update.

Example:
>>> Update().table("my_table").set_("x = 1").sql()
'UPDATE my_table SET x = 1'
Arguments:
  • expression : the SQL code strings to parse. If a Table instance is passed, this is used as-is. If another Expression instance is passed, it will be wrapped in a Table.
  • dialect: the dialect used to parse the input expression.
  • copy: if False, modify this expression instance in-place.
  • opts: other options to use to parse the input expressions.
Returns:

The modified Update expression.

def set_( self, *expressions: Union[str, Expression], append: bool = True, dialect: Union[str, sqlglot.dialects.Dialect, Type[sqlglot.dialects.Dialect], NoneType] = None, copy: bool = True, **opts) -> Update:
3447    def set_(
3448        self,
3449        *expressions: ExpOrStr,
3450        append: bool = True,
3451        dialect: DialectType = None,
3452        copy: bool = True,
3453        **opts,
3454    ) -> Update:
3455        """
3456        Append to or set the SET expressions.
3457
3458        Example:
3459            >>> Update().table("my_table").set_("x = 1").sql()
3460            'UPDATE my_table SET x = 1'
3461
3462        Args:
3463            *expressions: the SQL code strings to parse.
3464                If `Expression` instance(s) are passed, they will be used as-is.
3465                Multiple expressions are combined with a comma.
3466            append: if `True`, add the new expressions to any existing SET expressions.
3467                Otherwise, this resets the expressions.
3468            dialect: the dialect used to parse the input expressions.
3469            copy: if `False`, modify this expression instance in-place.
3470            opts: other options to use to parse the input expressions.
3471        """
3472        return _apply_list_builder(
3473            *expressions,
3474            instance=self,
3475            arg="expressions",
3476            append=append,
3477            into=Expression,
3478            prefix=None,
3479            dialect=dialect,
3480            copy=copy,
3481            **opts,
3482        )

Append to or set the SET expressions.

Example:
>>> Update().table("my_table").set_("x = 1").sql()
'UPDATE my_table SET x = 1'
Arguments:
  • *expressions: the SQL code strings to parse. If Expression instance(s) are passed, they will be used as-is. Multiple expressions are combined with a comma.
  • append: if True, add the new expressions to any existing SET expressions. Otherwise, this resets the expressions.
  • dialect: the dialect used to parse the input expressions.
  • copy: if False, modify this expression instance in-place.
  • opts: other options to use to parse the input expressions.
def where( self, *expressions: Union[str, Expression, NoneType], append: bool = True, dialect: Union[str, sqlglot.dialects.Dialect, Type[sqlglot.dialects.Dialect], NoneType] = None, copy: bool = True, **opts) -> Select:
3484    def where(
3485        self,
3486        *expressions: t.Optional[ExpOrStr],
3487        append: bool = True,
3488        dialect: DialectType = None,
3489        copy: bool = True,
3490        **opts,
3491    ) -> Select:
3492        """
3493        Append to or set the WHERE expressions.
3494
3495        Example:
3496            >>> Update().table("tbl").set_("x = 1").where("x = 'a' OR x < 'b'").sql()
3497            "UPDATE tbl SET x = 1 WHERE x = 'a' OR x < 'b'"
3498
3499        Args:
3500            *expressions: the SQL code strings to parse.
3501                If an `Expression` instance is passed, it will be used as-is.
3502                Multiple expressions are combined with an AND operator.
3503            append: if `True`, AND the new expressions to any existing expression.
3504                Otherwise, this resets the expression.
3505            dialect: the dialect used to parse the input expressions.
3506            copy: if `False`, modify this expression instance in-place.
3507            opts: other options to use to parse the input expressions.
3508
3509        Returns:
3510            Select: the modified expression.
3511        """
3512        return _apply_conjunction_builder(
3513            *expressions,
3514            instance=self,
3515            arg="where",
3516            append=append,
3517            into=Where,
3518            dialect=dialect,
3519            copy=copy,
3520            **opts,
3521        )

Append to or set the WHERE expressions.

Example:
>>> Update().table("tbl").set_("x = 1").where("x = 'a' OR x < 'b'").sql()
"UPDATE tbl SET x = 1 WHERE x = 'a' OR x < 'b'"
Arguments:
  • *expressions: the SQL code strings to parse. If an Expression instance is passed, it will be used as-is. Multiple expressions are combined with an AND operator.
  • append: if True, AND the new expressions to any existing expression. Otherwise, this resets the expression.
  • dialect: the dialect used to parse the input expressions.
  • copy: if False, modify this expression instance in-place.
  • opts: other options to use to parse the input expressions.
Returns:

Select: the modified expression.

def from_( self, expression: Union[str, Expression, NoneType] = None, dialect: Union[str, sqlglot.dialects.Dialect, Type[sqlglot.dialects.Dialect], NoneType] = None, copy: bool = True, **opts) -> Update:
3523    def from_(
3524        self,
3525        expression: t.Optional[ExpOrStr] = None,
3526        dialect: DialectType = None,
3527        copy: bool = True,
3528        **opts,
3529    ) -> Update:
3530        """
3531        Set the FROM expression.
3532
3533        Example:
3534            >>> Update().table("my_table").set_("x = 1").from_("baz").sql()
3535            'UPDATE my_table SET x = 1 FROM baz'
3536
3537        Args:
3538            expression : the SQL code strings to parse.
3539                If a `From` instance is passed, this is used as-is.
3540                If another `Expression` instance is passed, it will be wrapped in a `From`.
3541                If nothing is passed in then a from is not applied to the expression
3542            dialect: the dialect used to parse the input expression.
3543            copy: if `False`, modify this expression instance in-place.
3544            opts: other options to use to parse the input expressions.
3545
3546        Returns:
3547            The modified Update expression.
3548        """
3549        if not expression:
3550            return maybe_copy(self, copy)
3551
3552        return _apply_builder(
3553            expression=expression,
3554            instance=self,
3555            arg="from",
3556            into=From,
3557            prefix="FROM",
3558            dialect=dialect,
3559            copy=copy,
3560            **opts,
3561        )

Set the FROM expression.

Example:
>>> Update().table("my_table").set_("x = 1").from_("baz").sql()
'UPDATE my_table SET x = 1 FROM baz'
Arguments:
  • expression : the SQL code strings to parse. If a From instance is passed, this is used as-is. If another Expression instance is passed, it will be wrapped in a From. If nothing is passed in then a from is not applied to the expression
  • dialect: the dialect used to parse the input expression.
  • copy: if False, modify this expression instance in-place.
  • opts: other options to use to parse the input expressions.
Returns:

The modified Update expression.

def with_( self, alias: Union[str, Expression], as_: Union[str, Expression], recursive: Optional[bool] = None, materialized: Optional[bool] = None, append: bool = True, dialect: Union[str, sqlglot.dialects.Dialect, Type[sqlglot.dialects.Dialect], NoneType] = None, copy: bool = True, **opts) -> Update:
3563    def with_(
3564        self,
3565        alias: ExpOrStr,
3566        as_: ExpOrStr,
3567        recursive: t.Optional[bool] = None,
3568        materialized: t.Optional[bool] = None,
3569        append: bool = True,
3570        dialect: DialectType = None,
3571        copy: bool = True,
3572        **opts,
3573    ) -> Update:
3574        """
3575        Append to or set the common table expressions.
3576
3577        Example:
3578            >>> Update().table("my_table").set_("x = 1").from_("baz").with_("baz", "SELECT id FROM foo").sql()
3579            'WITH baz AS (SELECT id FROM foo) UPDATE my_table SET x = 1 FROM baz'
3580
3581        Args:
3582            alias: the SQL code string to parse as the table name.
3583                If an `Expression` instance is passed, this is used as-is.
3584            as_: the SQL code string to parse as the table expression.
3585                If an `Expression` instance is passed, it will be used as-is.
3586            recursive: set the RECURSIVE part of the expression. Defaults to `False`.
3587            materialized: set the MATERIALIZED part of the expression.
3588            append: if `True`, add to any existing expressions.
3589                Otherwise, this resets the expressions.
3590            dialect: the dialect used to parse the input expression.
3591            copy: if `False`, modify this expression instance in-place.
3592            opts: other options to use to parse the input expressions.
3593
3594        Returns:
3595            The modified expression.
3596        """
3597        return _apply_cte_builder(
3598            self,
3599            alias,
3600            as_,
3601            recursive=recursive,
3602            materialized=materialized,
3603            append=append,
3604            dialect=dialect,
3605            copy=copy,
3606            **opts,
3607        )

Append to or set the common table expressions.

Example:
>>> Update().table("my_table").set_("x = 1").from_("baz").with_("baz", "SELECT id FROM foo").sql()
'WITH baz AS (SELECT id FROM foo) UPDATE my_table SET x = 1 FROM baz'
Arguments:
  • alias: the SQL code string to parse as the table name. If an Expression instance is passed, this is used as-is.
  • as_: the SQL code string to parse as the table expression. If an Expression instance is passed, it will be used as-is.
  • recursive: set the RECURSIVE part of the expression. Defaults to False.
  • materialized: set the MATERIALIZED part of the expression.
  • append: if True, add to any existing expressions. Otherwise, this resets the expressions.
  • dialect: the dialect used to parse the input expression.
  • copy: if False, modify this expression instance in-place.
  • opts: other options to use to parse the input expressions.
Returns:

The modified expression.

key = 'update'
class Values(UDTF):
3610class Values(UDTF):
3611    arg_types = {"expressions": True, "alias": False}
arg_types = {'expressions': True, 'alias': False}
key = 'values'
class Var(Expression):
3614class Var(Expression):
3615    pass
key = 'var'
class Version(Expression):
3618class Version(Expression):
3619    """
3620    Time travel, iceberg, bigquery etc
3621    https://trino.io/docs/current/connector/iceberg.html?highlight=snapshot#using-snapshots
3622    https://www.databricks.com/blog/2019/02/04/introducing-delta-time-travel-for-large-scale-data-lakes.html
3623    https://cloud.google.com/bigquery/docs/reference/standard-sql/query-syntax#for_system_time_as_of
3624    https://learn.microsoft.com/en-us/sql/relational-databases/tables/querying-data-in-a-system-versioned-temporal-table?view=sql-server-ver16
3625    this is either TIMESTAMP or VERSION
3626    kind is ("AS OF", "BETWEEN")
3627    """
3628
3629    arg_types = {"this": True, "kind": True, "expression": False}
arg_types = {'this': True, 'kind': True, 'expression': False}
key = 'version'
class Schema(Expression):
3632class Schema(Expression):
3633    arg_types = {"this": False, "expressions": False}
arg_types = {'this': False, 'expressions': False}
key = 'schema'
class Lock(Expression):
3638class Lock(Expression):
3639    arg_types = {"update": True, "expressions": False, "wait": False}
arg_types = {'update': True, 'expressions': False, 'wait': False}
key = 'lock'
class Select(Query):
3642class Select(Query):
3643    arg_types = {
3644        "with": False,
3645        "kind": False,
3646        "expressions": False,
3647        "hint": False,
3648        "distinct": False,
3649        "into": False,
3650        "from": False,
3651        "operation_modifiers": False,
3652        **QUERY_MODIFIERS,
3653    }
3654
3655    def from_(
3656        self, expression: ExpOrStr, dialect: DialectType = None, copy: bool = True, **opts
3657    ) -> Select:
3658        """
3659        Set the FROM expression.
3660
3661        Example:
3662            >>> Select().from_("tbl").select("x").sql()
3663            'SELECT x FROM tbl'
3664
3665        Args:
3666            expression : the SQL code strings to parse.
3667                If a `From` instance is passed, this is used as-is.
3668                If another `Expression` instance is passed, it will be wrapped in a `From`.
3669            dialect: the dialect used to parse the input expression.
3670            copy: if `False`, modify this expression instance in-place.
3671            opts: other options to use to parse the input expressions.
3672
3673        Returns:
3674            The modified Select expression.
3675        """
3676        return _apply_builder(
3677            expression=expression,
3678            instance=self,
3679            arg="from",
3680            into=From,
3681            prefix="FROM",
3682            dialect=dialect,
3683            copy=copy,
3684            **opts,
3685        )
3686
3687    def group_by(
3688        self,
3689        *expressions: t.Optional[ExpOrStr],
3690        append: bool = True,
3691        dialect: DialectType = None,
3692        copy: bool = True,
3693        **opts,
3694    ) -> Select:
3695        """
3696        Set the GROUP BY expression.
3697
3698        Example:
3699            >>> Select().from_("tbl").select("x", "COUNT(1)").group_by("x").sql()
3700            'SELECT x, COUNT(1) FROM tbl GROUP BY x'
3701
3702        Args:
3703            *expressions: the SQL code strings to parse.
3704                If a `Group` instance is passed, this is used as-is.
3705                If another `Expression` instance is passed, it will be wrapped in a `Group`.
3706                If nothing is passed in then a group by is not applied to the expression
3707            append: if `True`, add to any existing expressions.
3708                Otherwise, this flattens all the `Group` expression into a single expression.
3709            dialect: the dialect used to parse the input expression.
3710            copy: if `False`, modify this expression instance in-place.
3711            opts: other options to use to parse the input expressions.
3712
3713        Returns:
3714            The modified Select expression.
3715        """
3716        if not expressions:
3717            return self if not copy else self.copy()
3718
3719        return _apply_child_list_builder(
3720            *expressions,
3721            instance=self,
3722            arg="group",
3723            append=append,
3724            copy=copy,
3725            prefix="GROUP BY",
3726            into=Group,
3727            dialect=dialect,
3728            **opts,
3729        )
3730
3731    def sort_by(
3732        self,
3733        *expressions: t.Optional[ExpOrStr],
3734        append: bool = True,
3735        dialect: DialectType = None,
3736        copy: bool = True,
3737        **opts,
3738    ) -> Select:
3739        """
3740        Set the SORT BY expression.
3741
3742        Example:
3743            >>> Select().from_("tbl").select("x").sort_by("x DESC").sql(dialect="hive")
3744            'SELECT x FROM tbl SORT BY x DESC'
3745
3746        Args:
3747            *expressions: the SQL code strings to parse.
3748                If a `Group` instance is passed, this is used as-is.
3749                If another `Expression` instance is passed, it will be wrapped in a `SORT`.
3750            append: if `True`, add to any existing expressions.
3751                Otherwise, this flattens all the `Order` expression into a single expression.
3752            dialect: the dialect used to parse the input expression.
3753            copy: if `False`, modify this expression instance in-place.
3754            opts: other options to use to parse the input expressions.
3755
3756        Returns:
3757            The modified Select expression.
3758        """
3759        return _apply_child_list_builder(
3760            *expressions,
3761            instance=self,
3762            arg="sort",
3763            append=append,
3764            copy=copy,
3765            prefix="SORT BY",
3766            into=Sort,
3767            dialect=dialect,
3768            **opts,
3769        )
3770
3771    def cluster_by(
3772        self,
3773        *expressions: t.Optional[ExpOrStr],
3774        append: bool = True,
3775        dialect: DialectType = None,
3776        copy: bool = True,
3777        **opts,
3778    ) -> Select:
3779        """
3780        Set the CLUSTER BY expression.
3781
3782        Example:
3783            >>> Select().from_("tbl").select("x").cluster_by("x DESC").sql(dialect="hive")
3784            'SELECT x FROM tbl CLUSTER BY x DESC'
3785
3786        Args:
3787            *expressions: the SQL code strings to parse.
3788                If a `Group` instance is passed, this is used as-is.
3789                If another `Expression` instance is passed, it will be wrapped in a `Cluster`.
3790            append: if `True`, add to any existing expressions.
3791                Otherwise, this flattens all the `Order` expression into a single expression.
3792            dialect: the dialect used to parse the input expression.
3793            copy: if `False`, modify this expression instance in-place.
3794            opts: other options to use to parse the input expressions.
3795
3796        Returns:
3797            The modified Select expression.
3798        """
3799        return _apply_child_list_builder(
3800            *expressions,
3801            instance=self,
3802            arg="cluster",
3803            append=append,
3804            copy=copy,
3805            prefix="CLUSTER BY",
3806            into=Cluster,
3807            dialect=dialect,
3808            **opts,
3809        )
3810
3811    def select(
3812        self,
3813        *expressions: t.Optional[ExpOrStr],
3814        append: bool = True,
3815        dialect: DialectType = None,
3816        copy: bool = True,
3817        **opts,
3818    ) -> Select:
3819        return _apply_list_builder(
3820            *expressions,
3821            instance=self,
3822            arg="expressions",
3823            append=append,
3824            dialect=dialect,
3825            into=Expression,
3826            copy=copy,
3827            **opts,
3828        )
3829
3830    def lateral(
3831        self,
3832        *expressions: t.Optional[ExpOrStr],
3833        append: bool = True,
3834        dialect: DialectType = None,
3835        copy: bool = True,
3836        **opts,
3837    ) -> Select:
3838        """
3839        Append to or set the LATERAL expressions.
3840
3841        Example:
3842            >>> Select().select("x").lateral("OUTER explode(y) tbl2 AS z").from_("tbl").sql()
3843            'SELECT x FROM tbl LATERAL VIEW OUTER EXPLODE(y) tbl2 AS z'
3844
3845        Args:
3846            *expressions: the SQL code strings to parse.
3847                If an `Expression` instance is passed, it will be used as-is.
3848            append: if `True`, add to any existing expressions.
3849                Otherwise, this resets the expressions.
3850            dialect: the dialect used to parse the input expressions.
3851            copy: if `False`, modify this expression instance in-place.
3852            opts: other options to use to parse the input expressions.
3853
3854        Returns:
3855            The modified Select expression.
3856        """
3857        return _apply_list_builder(
3858            *expressions,
3859            instance=self,
3860            arg="laterals",
3861            append=append,
3862            into=Lateral,
3863            prefix="LATERAL VIEW",
3864            dialect=dialect,
3865            copy=copy,
3866            **opts,
3867        )
3868
3869    def join(
3870        self,
3871        expression: ExpOrStr,
3872        on: t.Optional[ExpOrStr] = None,
3873        using: t.Optional[ExpOrStr | t.Collection[ExpOrStr]] = None,
3874        append: bool = True,
3875        join_type: t.Optional[str] = None,
3876        join_alias: t.Optional[Identifier | str] = None,
3877        dialect: DialectType = None,
3878        copy: bool = True,
3879        **opts,
3880    ) -> Select:
3881        """
3882        Append to or set the JOIN expressions.
3883
3884        Example:
3885            >>> Select().select("*").from_("tbl").join("tbl2", on="tbl1.y = tbl2.y").sql()
3886            'SELECT * FROM tbl JOIN tbl2 ON tbl1.y = tbl2.y'
3887
3888            >>> Select().select("1").from_("a").join("b", using=["x", "y", "z"]).sql()
3889            'SELECT 1 FROM a JOIN b USING (x, y, z)'
3890
3891            Use `join_type` to change the type of join:
3892
3893            >>> Select().select("*").from_("tbl").join("tbl2", on="tbl1.y = tbl2.y", join_type="left outer").sql()
3894            'SELECT * FROM tbl LEFT OUTER JOIN tbl2 ON tbl1.y = tbl2.y'
3895
3896        Args:
3897            expression: the SQL code string to parse.
3898                If an `Expression` instance is passed, it will be used as-is.
3899            on: optionally specify the join "on" criteria as a SQL string.
3900                If an `Expression` instance is passed, it will be used as-is.
3901            using: optionally specify the join "using" criteria as a SQL string.
3902                If an `Expression` instance is passed, it will be used as-is.
3903            append: if `True`, add to any existing expressions.
3904                Otherwise, this resets the expressions.
3905            join_type: if set, alter the parsed join type.
3906            join_alias: an optional alias for the joined source.
3907            dialect: the dialect used to parse the input expressions.
3908            copy: if `False`, modify this expression instance in-place.
3909            opts: other options to use to parse the input expressions.
3910
3911        Returns:
3912            Select: the modified expression.
3913        """
3914        parse_args: t.Dict[str, t.Any] = {"dialect": dialect, **opts}
3915
3916        try:
3917            expression = maybe_parse(expression, into=Join, prefix="JOIN", **parse_args)
3918        except ParseError:
3919            expression = maybe_parse(expression, into=(Join, Expression), **parse_args)
3920
3921        join = expression if isinstance(expression, Join) else Join(this=expression)
3922
3923        if isinstance(join.this, Select):
3924            join.this.replace(join.this.subquery())
3925
3926        if join_type:
3927            method: t.Optional[Token]
3928            side: t.Optional[Token]
3929            kind: t.Optional[Token]
3930
3931            method, side, kind = maybe_parse(join_type, into="JOIN_TYPE", **parse_args)  # type: ignore
3932
3933            if method:
3934                join.set("method", method.text)
3935            if side:
3936                join.set("side", side.text)
3937            if kind:
3938                join.set("kind", kind.text)
3939
3940        if on:
3941            on = and_(*ensure_list(on), dialect=dialect, copy=copy, **opts)
3942            join.set("on", on)
3943
3944        if using:
3945            join = _apply_list_builder(
3946                *ensure_list(using),
3947                instance=join,
3948                arg="using",
3949                append=append,
3950                copy=copy,
3951                into=Identifier,
3952                **opts,
3953            )
3954
3955        if join_alias:
3956            join.set("this", alias_(join.this, join_alias, table=True))
3957
3958        return _apply_list_builder(
3959            join,
3960            instance=self,
3961            arg="joins",
3962            append=append,
3963            copy=copy,
3964            **opts,
3965        )
3966
3967    def where(
3968        self,
3969        *expressions: t.Optional[ExpOrStr],
3970        append: bool = True,
3971        dialect: DialectType = None,
3972        copy: bool = True,
3973        **opts,
3974    ) -> Select:
3975        """
3976        Append to or set the WHERE expressions.
3977
3978        Example:
3979            >>> Select().select("x").from_("tbl").where("x = 'a' OR x < 'b'").sql()
3980            "SELECT x FROM tbl WHERE x = 'a' OR x < 'b'"
3981
3982        Args:
3983            *expressions: the SQL code strings to parse.
3984                If an `Expression` instance is passed, it will be used as-is.
3985                Multiple expressions are combined with an AND operator.
3986            append: if `True`, AND the new expressions to any existing expression.
3987                Otherwise, this resets the expression.
3988            dialect: the dialect used to parse the input expressions.
3989            copy: if `False`, modify this expression instance in-place.
3990            opts: other options to use to parse the input expressions.
3991
3992        Returns:
3993            Select: the modified expression.
3994        """
3995        return _apply_conjunction_builder(
3996            *expressions,
3997            instance=self,
3998            arg="where",
3999            append=append,
4000            into=Where,
4001            dialect=dialect,
4002            copy=copy,
4003            **opts,
4004        )
4005
4006    def having(
4007        self,
4008        *expressions: t.Optional[ExpOrStr],
4009        append: bool = True,
4010        dialect: DialectType = None,
4011        copy: bool = True,
4012        **opts,
4013    ) -> Select:
4014        """
4015        Append to or set the HAVING expressions.
4016
4017        Example:
4018            >>> Select().select("x", "COUNT(y)").from_("tbl").group_by("x").having("COUNT(y) > 3").sql()
4019            'SELECT x, COUNT(y) FROM tbl GROUP BY x HAVING COUNT(y) > 3'
4020
4021        Args:
4022            *expressions: the SQL code strings to parse.
4023                If an `Expression` instance is passed, it will be used as-is.
4024                Multiple expressions are combined with an AND operator.
4025            append: if `True`, AND the new expressions to any existing expression.
4026                Otherwise, this resets the expression.
4027            dialect: the dialect used to parse the input expressions.
4028            copy: if `False`, modify this expression instance in-place.
4029            opts: other options to use to parse the input expressions.
4030
4031        Returns:
4032            The modified Select expression.
4033        """
4034        return _apply_conjunction_builder(
4035            *expressions,
4036            instance=self,
4037            arg="having",
4038            append=append,
4039            into=Having,
4040            dialect=dialect,
4041            copy=copy,
4042            **opts,
4043        )
4044
4045    def window(
4046        self,
4047        *expressions: t.Optional[ExpOrStr],
4048        append: bool = True,
4049        dialect: DialectType = None,
4050        copy: bool = True,
4051        **opts,
4052    ) -> Select:
4053        return _apply_list_builder(
4054            *expressions,
4055            instance=self,
4056            arg="windows",
4057            append=append,
4058            into=Window,
4059            dialect=dialect,
4060            copy=copy,
4061            **opts,
4062        )
4063
4064    def qualify(
4065        self,
4066        *expressions: t.Optional[ExpOrStr],
4067        append: bool = True,
4068        dialect: DialectType = None,
4069        copy: bool = True,
4070        **opts,
4071    ) -> Select:
4072        return _apply_conjunction_builder(
4073            *expressions,
4074            instance=self,
4075            arg="qualify",
4076            append=append,
4077            into=Qualify,
4078            dialect=dialect,
4079            copy=copy,
4080            **opts,
4081        )
4082
4083    def distinct(
4084        self, *ons: t.Optional[ExpOrStr], distinct: bool = True, copy: bool = True
4085    ) -> Select:
4086        """
4087        Set the OFFSET expression.
4088
4089        Example:
4090            >>> Select().from_("tbl").select("x").distinct().sql()
4091            'SELECT DISTINCT x FROM tbl'
4092
4093        Args:
4094            ons: the expressions to distinct on
4095            distinct: whether the Select should be distinct
4096            copy: if `False`, modify this expression instance in-place.
4097
4098        Returns:
4099            Select: the modified expression.
4100        """
4101        instance = maybe_copy(self, copy)
4102        on = Tuple(expressions=[maybe_parse(on, copy=copy) for on in ons if on]) if ons else None
4103        instance.set("distinct", Distinct(on=on) if distinct else None)
4104        return instance
4105
4106    def ctas(
4107        self,
4108        table: ExpOrStr,
4109        properties: t.Optional[t.Dict] = None,
4110        dialect: DialectType = None,
4111        copy: bool = True,
4112        **opts,
4113    ) -> Create:
4114        """
4115        Convert this expression to a CREATE TABLE AS statement.
4116
4117        Example:
4118            >>> Select().select("*").from_("tbl").ctas("x").sql()
4119            'CREATE TABLE x AS SELECT * FROM tbl'
4120
4121        Args:
4122            table: the SQL code string to parse as the table name.
4123                If another `Expression` instance is passed, it will be used as-is.
4124            properties: an optional mapping of table properties
4125            dialect: the dialect used to parse the input table.
4126            copy: if `False`, modify this expression instance in-place.
4127            opts: other options to use to parse the input table.
4128
4129        Returns:
4130            The new Create expression.
4131        """
4132        instance = maybe_copy(self, copy)
4133        table_expression = maybe_parse(table, into=Table, dialect=dialect, **opts)
4134
4135        properties_expression = None
4136        if properties:
4137            properties_expression = Properties.from_dict(properties)
4138
4139        return Create(
4140            this=table_expression,
4141            kind="TABLE",
4142            expression=instance,
4143            properties=properties_expression,
4144        )
4145
4146    def lock(self, update: bool = True, copy: bool = True) -> Select:
4147        """
4148        Set the locking read mode for this expression.
4149
4150        Examples:
4151            >>> Select().select("x").from_("tbl").where("x = 'a'").lock().sql("mysql")
4152            "SELECT x FROM tbl WHERE x = 'a' FOR UPDATE"
4153
4154            >>> Select().select("x").from_("tbl").where("x = 'a'").lock(update=False).sql("mysql")
4155            "SELECT x FROM tbl WHERE x = 'a' FOR SHARE"
4156
4157        Args:
4158            update: if `True`, the locking type will be `FOR UPDATE`, else it will be `FOR SHARE`.
4159            copy: if `False`, modify this expression instance in-place.
4160
4161        Returns:
4162            The modified expression.
4163        """
4164        inst = maybe_copy(self, copy)
4165        inst.set("locks", [Lock(update=update)])
4166
4167        return inst
4168
4169    def hint(self, *hints: ExpOrStr, dialect: DialectType = None, copy: bool = True) -> Select:
4170        """
4171        Set hints for this expression.
4172
4173        Examples:
4174            >>> Select().select("x").from_("tbl").hint("BROADCAST(y)").sql(dialect="spark")
4175            'SELECT /*+ BROADCAST(y) */ x FROM tbl'
4176
4177        Args:
4178            hints: The SQL code strings to parse as the hints.
4179                If an `Expression` instance is passed, it will be used as-is.
4180            dialect: The dialect used to parse the hints.
4181            copy: If `False`, modify this expression instance in-place.
4182
4183        Returns:
4184            The modified expression.
4185        """
4186        inst = maybe_copy(self, copy)
4187        inst.set(
4188            "hint", Hint(expressions=[maybe_parse(h, copy=copy, dialect=dialect) for h in hints])
4189        )
4190
4191        return inst
4192
4193    @property
4194    def named_selects(self) -> t.List[str]:
4195        return [e.output_name for e in self.expressions if e.alias_or_name]
4196
4197    @property
4198    def is_star(self) -> bool:
4199        return any(expression.is_star for expression in self.expressions)
4200
4201    @property
4202    def selects(self) -> t.List[Expression]:
4203        return self.expressions
arg_types = {'with': False, 'kind': False, 'expressions': False, 'hint': False, 'distinct': False, 'into': False, 'from': False, 'operation_modifiers': False, 'match': False, 'laterals': False, 'joins': False, 'connect': False, 'pivots': False, 'prewhere': False, 'where': False, 'group': False, 'having': False, 'qualify': False, 'windows': False, 'distribute': False, 'sort': False, 'cluster': False, 'order': False, 'limit': False, 'offset': False, 'locks': False, 'sample': False, 'settings': False, 'format': False, 'options': False}
def from_( self, expression: Union[str, Expression], dialect: Union[str, sqlglot.dialects.Dialect, Type[sqlglot.dialects.Dialect], NoneType] = None, copy: bool = True, **opts) -> Select:
3655    def from_(
3656        self, expression: ExpOrStr, dialect: DialectType = None, copy: bool = True, **opts
3657    ) -> Select:
3658        """
3659        Set the FROM expression.
3660
3661        Example:
3662            >>> Select().from_("tbl").select("x").sql()
3663            'SELECT x FROM tbl'
3664
3665        Args:
3666            expression : the SQL code strings to parse.
3667                If a `From` instance is passed, this is used as-is.
3668                If another `Expression` instance is passed, it will be wrapped in a `From`.
3669            dialect: the dialect used to parse the input expression.
3670            copy: if `False`, modify this expression instance in-place.
3671            opts: other options to use to parse the input expressions.
3672
3673        Returns:
3674            The modified Select expression.
3675        """
3676        return _apply_builder(
3677            expression=expression,
3678            instance=self,
3679            arg="from",
3680            into=From,
3681            prefix="FROM",
3682            dialect=dialect,
3683            copy=copy,
3684            **opts,
3685        )

Set the FROM expression.

Example:
>>> Select().from_("tbl").select("x").sql()
'SELECT x FROM tbl'
Arguments:
  • expression : the SQL code strings to parse. If a From instance is passed, this is used as-is. If another Expression instance is passed, it will be wrapped in a From.
  • dialect: the dialect used to parse the input expression.
  • copy: if False, modify this expression instance in-place.
  • opts: other options to use to parse the input expressions.
Returns:

The modified Select expression.

def group_by( self, *expressions: Union[str, Expression, NoneType], append: bool = True, dialect: Union[str, sqlglot.dialects.Dialect, Type[sqlglot.dialects.Dialect], NoneType] = None, copy: bool = True, **opts) -> Select:
3687    def group_by(
3688        self,
3689        *expressions: t.Optional[ExpOrStr],
3690        append: bool = True,
3691        dialect: DialectType = None,
3692        copy: bool = True,
3693        **opts,
3694    ) -> Select:
3695        """
3696        Set the GROUP BY expression.
3697
3698        Example:
3699            >>> Select().from_("tbl").select("x", "COUNT(1)").group_by("x").sql()
3700            'SELECT x, COUNT(1) FROM tbl GROUP BY x'
3701
3702        Args:
3703            *expressions: the SQL code strings to parse.
3704                If a `Group` instance is passed, this is used as-is.
3705                If another `Expression` instance is passed, it will be wrapped in a `Group`.
3706                If nothing is passed in then a group by is not applied to the expression
3707            append: if `True`, add to any existing expressions.
3708                Otherwise, this flattens all the `Group` expression into a single expression.
3709            dialect: the dialect used to parse the input expression.
3710            copy: if `False`, modify this expression instance in-place.
3711            opts: other options to use to parse the input expressions.
3712
3713        Returns:
3714            The modified Select expression.
3715        """
3716        if not expressions:
3717            return self if not copy else self.copy()
3718
3719        return _apply_child_list_builder(
3720            *expressions,
3721            instance=self,
3722            arg="group",
3723            append=append,
3724            copy=copy,
3725            prefix="GROUP BY",
3726            into=Group,
3727            dialect=dialect,
3728            **opts,
3729        )

Set the GROUP BY expression.

Example:
>>> Select().from_("tbl").select("x", "COUNT(1)").group_by("x").sql()
'SELECT x, COUNT(1) FROM tbl GROUP BY x'
Arguments:
  • *expressions: the SQL code strings to parse. If a Group instance is passed, this is used as-is. If another Expression instance is passed, it will be wrapped in a Group. If nothing is passed in then a group by is not applied to the expression
  • append: if True, add to any existing expressions. Otherwise, this flattens all the Group expression into a single expression.
  • dialect: the dialect used to parse the input expression.
  • copy: if False, modify this expression instance in-place.
  • opts: other options to use to parse the input expressions.
Returns:

The modified Select expression.

def sort_by( self, *expressions: Union[str, Expression, NoneType], append: bool = True, dialect: Union[str, sqlglot.dialects.Dialect, Type[sqlglot.dialects.Dialect], NoneType] = None, copy: bool = True, **opts) -> Select:
3731    def sort_by(
3732        self,
3733        *expressions: t.Optional[ExpOrStr],
3734        append: bool = True,
3735        dialect: DialectType = None,
3736        copy: bool = True,
3737        **opts,
3738    ) -> Select:
3739        """
3740        Set the SORT BY expression.
3741
3742        Example:
3743            >>> Select().from_("tbl").select("x").sort_by("x DESC").sql(dialect="hive")
3744            'SELECT x FROM tbl SORT BY x DESC'
3745
3746        Args:
3747            *expressions: the SQL code strings to parse.
3748                If a `Group` instance is passed, this is used as-is.
3749                If another `Expression` instance is passed, it will be wrapped in a `SORT`.
3750            append: if `True`, add to any existing expressions.
3751                Otherwise, this flattens all the `Order` expression into a single expression.
3752            dialect: the dialect used to parse the input expression.
3753            copy: if `False`, modify this expression instance in-place.
3754            opts: other options to use to parse the input expressions.
3755
3756        Returns:
3757            The modified Select expression.
3758        """
3759        return _apply_child_list_builder(
3760            *expressions,
3761            instance=self,
3762            arg="sort",
3763            append=append,
3764            copy=copy,
3765            prefix="SORT BY",
3766            into=Sort,
3767            dialect=dialect,
3768            **opts,
3769        )

Set the SORT BY expression.

Example:
>>> Select().from_("tbl").select("x").sort_by("x DESC").sql(dialect="hive")
'SELECT x FROM tbl SORT BY x DESC'
Arguments:
  • *expressions: the SQL code strings to parse. If a Group instance is passed, this is used as-is. If another Expression instance is passed, it will be wrapped in a SORT.
  • append: if True, add to any existing expressions. Otherwise, this flattens all the Order expression into a single expression.
  • dialect: the dialect used to parse the input expression.
  • copy: if False, modify this expression instance in-place.
  • opts: other options to use to parse the input expressions.
Returns:

The modified Select expression.

def cluster_by( self, *expressions: Union[str, Expression, NoneType], append: bool = True, dialect: Union[str, sqlglot.dialects.Dialect, Type[sqlglot.dialects.Dialect], NoneType] = None, copy: bool = True, **opts) -> Select:
3771    def cluster_by(
3772        self,
3773        *expressions: t.Optional[ExpOrStr],
3774        append: bool = True,
3775        dialect: DialectType = None,
3776        copy: bool = True,
3777        **opts,
3778    ) -> Select:
3779        """
3780        Set the CLUSTER BY expression.
3781
3782        Example:
3783            >>> Select().from_("tbl").select("x").cluster_by("x DESC").sql(dialect="hive")
3784            'SELECT x FROM tbl CLUSTER BY x DESC'
3785
3786        Args:
3787            *expressions: the SQL code strings to parse.
3788                If a `Group` instance is passed, this is used as-is.
3789                If another `Expression` instance is passed, it will be wrapped in a `Cluster`.
3790            append: if `True`, add to any existing expressions.
3791                Otherwise, this flattens all the `Order` expression into a single expression.
3792            dialect: the dialect used to parse the input expression.
3793            copy: if `False`, modify this expression instance in-place.
3794            opts: other options to use to parse the input expressions.
3795
3796        Returns:
3797            The modified Select expression.
3798        """
3799        return _apply_child_list_builder(
3800            *expressions,
3801            instance=self,
3802            arg="cluster",
3803            append=append,
3804            copy=copy,
3805            prefix="CLUSTER BY",
3806            into=Cluster,
3807            dialect=dialect,
3808            **opts,
3809        )

Set the CLUSTER BY expression.

Example:
>>> Select().from_("tbl").select("x").cluster_by("x DESC").sql(dialect="hive")
'SELECT x FROM tbl CLUSTER BY x DESC'
Arguments:
  • *expressions: the SQL code strings to parse. If a Group instance is passed, this is used as-is. If another Expression instance is passed, it will be wrapped in a Cluster.
  • append: if True, add to any existing expressions. Otherwise, this flattens all the Order expression into a single expression.
  • dialect: the dialect used to parse the input expression.
  • copy: if False, modify this expression instance in-place.
  • opts: other options to use to parse the input expressions.
Returns:

The modified Select expression.

def select( self, *expressions: Union[str, Expression, NoneType], append: bool = True, dialect: Union[str, sqlglot.dialects.Dialect, Type[sqlglot.dialects.Dialect], NoneType] = None, copy: bool = True, **opts) -> Select:
3811    def select(
3812        self,
3813        *expressions: t.Optional[ExpOrStr],
3814        append: bool = True,
3815        dialect: DialectType = None,
3816        copy: bool = True,
3817        **opts,
3818    ) -> Select:
3819        return _apply_list_builder(
3820            *expressions,
3821            instance=self,
3822            arg="expressions",
3823            append=append,
3824            dialect=dialect,
3825            into=Expression,
3826            copy=copy,
3827            **opts,
3828        )

Append to or set the SELECT expressions.

Example:
>>> Select().select("x", "y").sql()
'SELECT x, y'
Arguments:
  • *expressions: the SQL code strings to parse. If an Expression instance is passed, it will be used as-is.
  • append: if True, add to any existing expressions. Otherwise, this resets the expressions.
  • dialect: the dialect used to parse the input expressions.
  • copy: if False, modify this expression instance in-place.
  • opts: other options to use to parse the input expressions.
Returns:

The modified Query expression.

def lateral( self, *expressions: Union[str, Expression, NoneType], append: bool = True, dialect: Union[str, sqlglot.dialects.Dialect, Type[sqlglot.dialects.Dialect], NoneType] = None, copy: bool = True, **opts) -> Select:
3830    def lateral(
3831        self,
3832        *expressions: t.Optional[ExpOrStr],
3833        append: bool = True,
3834        dialect: DialectType = None,
3835        copy: bool = True,
3836        **opts,
3837    ) -> Select:
3838        """
3839        Append to or set the LATERAL expressions.
3840
3841        Example:
3842            >>> Select().select("x").lateral("OUTER explode(y) tbl2 AS z").from_("tbl").sql()
3843            'SELECT x FROM tbl LATERAL VIEW OUTER EXPLODE(y) tbl2 AS z'
3844
3845        Args:
3846            *expressions: the SQL code strings to parse.
3847                If an `Expression` instance is passed, it will be used as-is.
3848            append: if `True`, add to any existing expressions.
3849                Otherwise, this resets the expressions.
3850            dialect: the dialect used to parse the input expressions.
3851            copy: if `False`, modify this expression instance in-place.
3852            opts: other options to use to parse the input expressions.
3853
3854        Returns:
3855            The modified Select expression.
3856        """
3857        return _apply_list_builder(
3858            *expressions,
3859            instance=self,
3860            arg="laterals",
3861            append=append,
3862            into=Lateral,
3863            prefix="LATERAL VIEW",
3864            dialect=dialect,
3865            copy=copy,
3866            **opts,
3867        )

Append to or set the LATERAL expressions.

Example:
>>> Select().select("x").lateral("OUTER explode(y) tbl2 AS z").from_("tbl").sql()
'SELECT x FROM tbl LATERAL VIEW OUTER EXPLODE(y) tbl2 AS z'
Arguments:
  • *expressions: the SQL code strings to parse. If an Expression instance is passed, it will be used as-is.
  • append: if True, add to any existing expressions. Otherwise, this resets the expressions.
  • dialect: the dialect used to parse the input expressions.
  • copy: if False, modify this expression instance in-place.
  • opts: other options to use to parse the input expressions.
Returns:

The modified Select expression.

def join( self, expression: Union[str, Expression], on: Union[str, Expression, NoneType] = None, using: Union[str, Expression, Collection[Union[str, Expression]], NoneType] = None, append: bool = True, join_type: Optional[str] = None, join_alias: Union[Identifier, str, NoneType] = None, dialect: Union[str, sqlglot.dialects.Dialect, Type[sqlglot.dialects.Dialect], NoneType] = None, copy: bool = True, **opts) -> Select:
3869    def join(
3870        self,
3871        expression: ExpOrStr,
3872        on: t.Optional[ExpOrStr] = None,
3873        using: t.Optional[ExpOrStr | t.Collection[ExpOrStr]] = None,
3874        append: bool = True,
3875        join_type: t.Optional[str] = None,
3876        join_alias: t.Optional[Identifier | str] = None,
3877        dialect: DialectType = None,
3878        copy: bool = True,
3879        **opts,
3880    ) -> Select:
3881        """
3882        Append to or set the JOIN expressions.
3883
3884        Example:
3885            >>> Select().select("*").from_("tbl").join("tbl2", on="tbl1.y = tbl2.y").sql()
3886            'SELECT * FROM tbl JOIN tbl2 ON tbl1.y = tbl2.y'
3887
3888            >>> Select().select("1").from_("a").join("b", using=["x", "y", "z"]).sql()
3889            'SELECT 1 FROM a JOIN b USING (x, y, z)'
3890
3891            Use `join_type` to change the type of join:
3892
3893            >>> Select().select("*").from_("tbl").join("tbl2", on="tbl1.y = tbl2.y", join_type="left outer").sql()
3894            'SELECT * FROM tbl LEFT OUTER JOIN tbl2 ON tbl1.y = tbl2.y'
3895
3896        Args:
3897            expression: the SQL code string to parse.
3898                If an `Expression` instance is passed, it will be used as-is.
3899            on: optionally specify the join "on" criteria as a SQL string.
3900                If an `Expression` instance is passed, it will be used as-is.
3901            using: optionally specify the join "using" criteria as a SQL string.
3902                If an `Expression` instance is passed, it will be used as-is.
3903            append: if `True`, add to any existing expressions.
3904                Otherwise, this resets the expressions.
3905            join_type: if set, alter the parsed join type.
3906            join_alias: an optional alias for the joined source.
3907            dialect: the dialect used to parse the input expressions.
3908            copy: if `False`, modify this expression instance in-place.
3909            opts: other options to use to parse the input expressions.
3910
3911        Returns:
3912            Select: the modified expression.
3913        """
3914        parse_args: t.Dict[str, t.Any] = {"dialect": dialect, **opts}
3915
3916        try:
3917            expression = maybe_parse(expression, into=Join, prefix="JOIN", **parse_args)
3918        except ParseError:
3919            expression = maybe_parse(expression, into=(Join, Expression), **parse_args)
3920
3921        join = expression if isinstance(expression, Join) else Join(this=expression)
3922
3923        if isinstance(join.this, Select):
3924            join.this.replace(join.this.subquery())
3925
3926        if join_type:
3927            method: t.Optional[Token]
3928            side: t.Optional[Token]
3929            kind: t.Optional[Token]
3930
3931            method, side, kind = maybe_parse(join_type, into="JOIN_TYPE", **parse_args)  # type: ignore
3932
3933            if method:
3934                join.set("method", method.text)
3935            if side:
3936                join.set("side", side.text)
3937            if kind:
3938                join.set("kind", kind.text)
3939
3940        if on:
3941            on = and_(*ensure_list(on), dialect=dialect, copy=copy, **opts)
3942            join.set("on", on)
3943
3944        if using:
3945            join = _apply_list_builder(
3946                *ensure_list(using),
3947                instance=join,
3948                arg="using",
3949                append=append,
3950                copy=copy,
3951                into=Identifier,
3952                **opts,
3953            )
3954
3955        if join_alias:
3956            join.set("this", alias_(join.this, join_alias, table=True))
3957
3958        return _apply_list_builder(
3959            join,
3960            instance=self,
3961            arg="joins",
3962            append=append,
3963            copy=copy,
3964            **opts,
3965        )

Append to or set the JOIN expressions.

Example:
>>> Select().select("*").from_("tbl").join("tbl2", on="tbl1.y = tbl2.y").sql()
'SELECT * FROM tbl JOIN tbl2 ON tbl1.y = tbl2.y'
>>> Select().select("1").from_("a").join("b", using=["x", "y", "z"]).sql()
'SELECT 1 FROM a JOIN b USING (x, y, z)'

Use join_type to change the type of join:

>>> Select().select("*").from_("tbl").join("tbl2", on="tbl1.y = tbl2.y", join_type="left outer").sql()
'SELECT * FROM tbl LEFT OUTER JOIN tbl2 ON tbl1.y = tbl2.y'
Arguments:
  • expression: the SQL code string to parse. If an Expression instance is passed, it will be used as-is.
  • on: optionally specify the join "on" criteria as a SQL string. If an Expression instance is passed, it will be used as-is.
  • using: optionally specify the join "using" criteria as a SQL string. If an Expression instance is passed, it will be used as-is.
  • append: if True, add to any existing expressions. Otherwise, this resets the expressions.
  • join_type: if set, alter the parsed join type.
  • join_alias: an optional alias for the joined source.
  • dialect: the dialect used to parse the input expressions.
  • copy: if False, modify this expression instance in-place.
  • opts: other options to use to parse the input expressions.
Returns:

Select: the modified expression.

def where( self, *expressions: Union[str, Expression, NoneType], append: bool = True, dialect: Union[str, sqlglot.dialects.Dialect, Type[sqlglot.dialects.Dialect], NoneType] = None, copy: bool = True, **opts) -> Select:
3967    def where(
3968        self,
3969        *expressions: t.Optional[ExpOrStr],
3970        append: bool = True,
3971        dialect: DialectType = None,
3972        copy: bool = True,
3973        **opts,
3974    ) -> Select:
3975        """
3976        Append to or set the WHERE expressions.
3977
3978        Example:
3979            >>> Select().select("x").from_("tbl").where("x = 'a' OR x < 'b'").sql()
3980            "SELECT x FROM tbl WHERE x = 'a' OR x < 'b'"
3981
3982        Args:
3983            *expressions: the SQL code strings to parse.
3984                If an `Expression` instance is passed, it will be used as-is.
3985                Multiple expressions are combined with an AND operator.
3986            append: if `True`, AND the new expressions to any existing expression.
3987                Otherwise, this resets the expression.
3988            dialect: the dialect used to parse the input expressions.
3989            copy: if `False`, modify this expression instance in-place.
3990            opts: other options to use to parse the input expressions.
3991
3992        Returns:
3993            Select: the modified expression.
3994        """
3995        return _apply_conjunction_builder(
3996            *expressions,
3997            instance=self,
3998            arg="where",
3999            append=append,
4000            into=Where,
4001            dialect=dialect,
4002            copy=copy,
4003            **opts,
4004        )

Append to or set the WHERE expressions.

Example:
>>> Select().select("x").from_("tbl").where("x = 'a' OR x < 'b'").sql()
"SELECT x FROM tbl WHERE x = 'a' OR x < 'b'"
Arguments:
  • *expressions: the SQL code strings to parse. If an Expression instance is passed, it will be used as-is. Multiple expressions are combined with an AND operator.
  • append: if True, AND the new expressions to any existing expression. Otherwise, this resets the expression.
  • dialect: the dialect used to parse the input expressions.
  • copy: if False, modify this expression instance in-place.
  • opts: other options to use to parse the input expressions.
Returns:

Select: the modified expression.

def having( self, *expressions: Union[str, Expression, NoneType], append: bool = True, dialect: Union[str, sqlglot.dialects.Dialect, Type[sqlglot.dialects.Dialect], NoneType] = None, copy: bool = True, **opts) -> Select:
4006    def having(
4007        self,
4008        *expressions: t.Optional[ExpOrStr],
4009        append: bool = True,
4010        dialect: DialectType = None,
4011        copy: bool = True,
4012        **opts,
4013    ) -> Select:
4014        """
4015        Append to or set the HAVING expressions.
4016
4017        Example:
4018            >>> Select().select("x", "COUNT(y)").from_("tbl").group_by("x").having("COUNT(y) > 3").sql()
4019            'SELECT x, COUNT(y) FROM tbl GROUP BY x HAVING COUNT(y) > 3'
4020
4021        Args:
4022            *expressions: the SQL code strings to parse.
4023                If an `Expression` instance is passed, it will be used as-is.
4024                Multiple expressions are combined with an AND operator.
4025            append: if `True`, AND the new expressions to any existing expression.
4026                Otherwise, this resets the expression.
4027            dialect: the dialect used to parse the input expressions.
4028            copy: if `False`, modify this expression instance in-place.
4029            opts: other options to use to parse the input expressions.
4030
4031        Returns:
4032            The modified Select expression.
4033        """
4034        return _apply_conjunction_builder(
4035            *expressions,
4036            instance=self,
4037            arg="having",
4038            append=append,
4039            into=Having,
4040            dialect=dialect,
4041            copy=copy,
4042            **opts,
4043        )

Append to or set the HAVING expressions.

Example:
>>> Select().select("x", "COUNT(y)").from_("tbl").group_by("x").having("COUNT(y) > 3").sql()
'SELECT x, COUNT(y) FROM tbl GROUP BY x HAVING COUNT(y) > 3'
Arguments:
  • *expressions: the SQL code strings to parse. If an Expression instance is passed, it will be used as-is. Multiple expressions are combined with an AND operator.
  • append: if True, AND the new expressions to any existing expression. Otherwise, this resets the expression.
  • dialect: the dialect used to parse the input expressions.
  • copy: if False, modify this expression instance in-place.
  • opts: other options to use to parse the input expressions.
Returns:

The modified Select expression.

def window( self, *expressions: Union[str, Expression, NoneType], append: bool = True, dialect: Union[str, sqlglot.dialects.Dialect, Type[sqlglot.dialects.Dialect], NoneType] = None, copy: bool = True, **opts) -> Select:
4045    def window(
4046        self,
4047        *expressions: t.Optional[ExpOrStr],
4048        append: bool = True,
4049        dialect: DialectType = None,
4050        copy: bool = True,
4051        **opts,
4052    ) -> Select:
4053        return _apply_list_builder(
4054            *expressions,
4055            instance=self,
4056            arg="windows",
4057            append=append,
4058            into=Window,
4059            dialect=dialect,
4060            copy=copy,
4061            **opts,
4062        )
def qualify( self, *expressions: Union[str, Expression, NoneType], append: bool = True, dialect: Union[str, sqlglot.dialects.Dialect, Type[sqlglot.dialects.Dialect], NoneType] = None, copy: bool = True, **opts) -> Select:
4064    def qualify(
4065        self,
4066        *expressions: t.Optional[ExpOrStr],
4067        append: bool = True,
4068        dialect: DialectType = None,
4069        copy: bool = True,
4070        **opts,
4071    ) -> Select:
4072        return _apply_conjunction_builder(
4073            *expressions,
4074            instance=self,
4075            arg="qualify",
4076            append=append,
4077            into=Qualify,
4078            dialect=dialect,
4079            copy=copy,
4080            **opts,
4081        )
def distinct( self, *ons: Union[str, Expression, NoneType], distinct: bool = True, copy: bool = True) -> Select:
4083    def distinct(
4084        self, *ons: t.Optional[ExpOrStr], distinct: bool = True, copy: bool = True
4085    ) -> Select:
4086        """
4087        Set the OFFSET expression.
4088
4089        Example:
4090            >>> Select().from_("tbl").select("x").distinct().sql()
4091            'SELECT DISTINCT x FROM tbl'
4092
4093        Args:
4094            ons: the expressions to distinct on
4095            distinct: whether the Select should be distinct
4096            copy: if `False`, modify this expression instance in-place.
4097
4098        Returns:
4099            Select: the modified expression.
4100        """
4101        instance = maybe_copy(self, copy)
4102        on = Tuple(expressions=[maybe_parse(on, copy=copy) for on in ons if on]) if ons else None
4103        instance.set("distinct", Distinct(on=on) if distinct else None)
4104        return instance

Set the OFFSET expression.

Example:
>>> Select().from_("tbl").select("x").distinct().sql()
'SELECT DISTINCT x FROM tbl'
Arguments:
  • ons: the expressions to distinct on
  • distinct: whether the Select should be distinct
  • copy: if False, modify this expression instance in-place.
Returns:

Select: the modified expression.

def ctas( self, table: Union[str, Expression], properties: Optional[Dict] = None, dialect: Union[str, sqlglot.dialects.Dialect, Type[sqlglot.dialects.Dialect], NoneType] = None, copy: bool = True, **opts) -> Create:
4106    def ctas(
4107        self,
4108        table: ExpOrStr,
4109        properties: t.Optional[t.Dict] = None,
4110        dialect: DialectType = None,
4111        copy: bool = True,
4112        **opts,
4113    ) -> Create:
4114        """
4115        Convert this expression to a CREATE TABLE AS statement.
4116
4117        Example:
4118            >>> Select().select("*").from_("tbl").ctas("x").sql()
4119            'CREATE TABLE x AS SELECT * FROM tbl'
4120
4121        Args:
4122            table: the SQL code string to parse as the table name.
4123                If another `Expression` instance is passed, it will be used as-is.
4124            properties: an optional mapping of table properties
4125            dialect: the dialect used to parse the input table.
4126            copy: if `False`, modify this expression instance in-place.
4127            opts: other options to use to parse the input table.
4128
4129        Returns:
4130            The new Create expression.
4131        """
4132        instance = maybe_copy(self, copy)
4133        table_expression = maybe_parse(table, into=Table, dialect=dialect, **opts)
4134
4135        properties_expression = None
4136        if properties:
4137            properties_expression = Properties.from_dict(properties)
4138
4139        return Create(
4140            this=table_expression,
4141            kind="TABLE",
4142            expression=instance,
4143            properties=properties_expression,
4144        )

Convert this expression to a CREATE TABLE AS statement.

Example:
>>> Select().select("*").from_("tbl").ctas("x").sql()
'CREATE TABLE x AS SELECT * FROM tbl'
Arguments:
  • table: the SQL code string to parse as the table name. If another Expression instance is passed, it will be used as-is.
  • properties: an optional mapping of table properties
  • dialect: the dialect used to parse the input table.
  • copy: if False, modify this expression instance in-place.
  • opts: other options to use to parse the input table.
Returns:

The new Create expression.

def lock( self, update: bool = True, copy: bool = True) -> Select:
4146    def lock(self, update: bool = True, copy: bool = True) -> Select:
4147        """
4148        Set the locking read mode for this expression.
4149
4150        Examples:
4151            >>> Select().select("x").from_("tbl").where("x = 'a'").lock().sql("mysql")
4152            "SELECT x FROM tbl WHERE x = 'a' FOR UPDATE"
4153
4154            >>> Select().select("x").from_("tbl").where("x = 'a'").lock(update=False).sql("mysql")
4155            "SELECT x FROM tbl WHERE x = 'a' FOR SHARE"
4156
4157        Args:
4158            update: if `True`, the locking type will be `FOR UPDATE`, else it will be `FOR SHARE`.
4159            copy: if `False`, modify this expression instance in-place.
4160
4161        Returns:
4162            The modified expression.
4163        """
4164        inst = maybe_copy(self, copy)
4165        inst.set("locks", [Lock(update=update)])
4166
4167        return inst

Set the locking read mode for this expression.

Examples:
>>> Select().select("x").from_("tbl").where("x = 'a'").lock().sql("mysql")
"SELECT x FROM tbl WHERE x = 'a' FOR UPDATE"
>>> Select().select("x").from_("tbl").where("x = 'a'").lock(update=False).sql("mysql")
"SELECT x FROM tbl WHERE x = 'a' FOR SHARE"
Arguments:
  • update: if True, the locking type will be FOR UPDATE, else it will be FOR SHARE.
  • copy: if False, modify this expression instance in-place.
Returns:

The modified expression.

def hint( self, *hints: Union[str, Expression], dialect: Union[str, sqlglot.dialects.Dialect, Type[sqlglot.dialects.Dialect], NoneType] = None, copy: bool = True) -> Select:
4169    def hint(self, *hints: ExpOrStr, dialect: DialectType = None, copy: bool = True) -> Select:
4170        """
4171        Set hints for this expression.
4172
4173        Examples:
4174            >>> Select().select("x").from_("tbl").hint("BROADCAST(y)").sql(dialect="spark")
4175            'SELECT /*+ BROADCAST(y) */ x FROM tbl'
4176
4177        Args:
4178            hints: The SQL code strings to parse as the hints.
4179                If an `Expression` instance is passed, it will be used as-is.
4180            dialect: The dialect used to parse the hints.
4181            copy: If `False`, modify this expression instance in-place.
4182
4183        Returns:
4184            The modified expression.
4185        """
4186        inst = maybe_copy(self, copy)
4187        inst.set(
4188            "hint", Hint(expressions=[maybe_parse(h, copy=copy, dialect=dialect) for h in hints])
4189        )
4190
4191        return inst

Set hints for this expression.

Examples:
>>> Select().select("x").from_("tbl").hint("BROADCAST(y)").sql(dialect="spark")
'SELECT /*+ BROADCAST(y) */ x FROM tbl'
Arguments:
  • hints: The SQL code strings to parse as the hints. If an Expression instance is passed, it will be used as-is.
  • dialect: The dialect used to parse the hints.
  • copy: If False, modify this expression instance in-place.
Returns:

The modified expression.

named_selects: List[str]
4193    @property
4194    def named_selects(self) -> t.List[str]:
4195        return [e.output_name for e in self.expressions if e.alias_or_name]

Returns the output names of the query's projections.

is_star: bool
4197    @property
4198    def is_star(self) -> bool:
4199        return any(expression.is_star for expression in self.expressions)

Checks whether an expression is a star.

selects: List[Expression]
4201    @property
4202    def selects(self) -> t.List[Expression]:
4203        return self.expressions

Returns the query's projections.

key = 'select'
UNWRAPPED_QUERIES = (<class 'Select'>, <class 'SetOperation'>)
class Subquery(DerivedTable, Query):
4209class Subquery(DerivedTable, Query):
4210    arg_types = {
4211        "this": True,
4212        "alias": False,
4213        "with": False,
4214        **QUERY_MODIFIERS,
4215    }
4216
4217    def unnest(self):
4218        """Returns the first non subquery."""
4219        expression = self
4220        while isinstance(expression, Subquery):
4221            expression = expression.this
4222        return expression
4223
4224    def unwrap(self) -> Subquery:
4225        expression = self
4226        while expression.same_parent and expression.is_wrapper:
4227            expression = t.cast(Subquery, expression.parent)
4228        return expression
4229
4230    def select(
4231        self,
4232        *expressions: t.Optional[ExpOrStr],
4233        append: bool = True,
4234        dialect: DialectType = None,
4235        copy: bool = True,
4236        **opts,
4237    ) -> Subquery:
4238        this = maybe_copy(self, copy)
4239        this.unnest().select(*expressions, append=append, dialect=dialect, copy=False, **opts)
4240        return this
4241
4242    @property
4243    def is_wrapper(self) -> bool:
4244        """
4245        Whether this Subquery acts as a simple wrapper around another expression.
4246
4247        SELECT * FROM (((SELECT * FROM t)))
4248                      ^
4249                      This corresponds to a "wrapper" Subquery node
4250        """
4251        return all(v is None for k, v in self.args.items() if k != "this")
4252
4253    @property
4254    def is_star(self) -> bool:
4255        return self.this.is_star
4256
4257    @property
4258    def output_name(self) -> str:
4259        return self.alias
arg_types = {'this': True, 'alias': False, 'with': False, 'match': False, 'laterals': False, 'joins': False, 'connect': False, 'pivots': False, 'prewhere': False, 'where': False, 'group': False, 'having': False, 'qualify': False, 'windows': False, 'distribute': False, 'sort': False, 'cluster': False, 'order': False, 'limit': False, 'offset': False, 'locks': False, 'sample': False, 'settings': False, 'format': False, 'options': False}
def unnest(self):
4217    def unnest(self):
4218        """Returns the first non subquery."""
4219        expression = self
4220        while isinstance(expression, Subquery):
4221            expression = expression.this
4222        return expression

Returns the first non subquery.

def unwrap(self) -> Subquery:
4224    def unwrap(self) -> Subquery:
4225        expression = self
4226        while expression.same_parent and expression.is_wrapper:
4227            expression = t.cast(Subquery, expression.parent)
4228        return expression
def select( self, *expressions: Union[str, Expression, NoneType], append: bool = True, dialect: Union[str, sqlglot.dialects.Dialect, Type[sqlglot.dialects.Dialect], NoneType] = None, copy: bool = True, **opts) -> Subquery:
4230    def select(
4231        self,
4232        *expressions: t.Optional[ExpOrStr],
4233        append: bool = True,
4234        dialect: DialectType = None,
4235        copy: bool = True,
4236        **opts,
4237    ) -> Subquery:
4238        this = maybe_copy(self, copy)
4239        this.unnest().select(*expressions, append=append, dialect=dialect, copy=False, **opts)
4240        return this

Append to or set the SELECT expressions.

Example:
>>> Select().select("x", "y").sql()
'SELECT x, y'
Arguments:
  • *expressions: the SQL code strings to parse. If an Expression instance is passed, it will be used as-is.
  • append: if True, add to any existing expressions. Otherwise, this resets the expressions.
  • dialect: the dialect used to parse the input expressions.
  • copy: if False, modify this expression instance in-place.
  • opts: other options to use to parse the input expressions.
Returns:

The modified Query expression.

is_wrapper: bool
4242    @property
4243    def is_wrapper(self) -> bool:
4244        """
4245        Whether this Subquery acts as a simple wrapper around another expression.
4246
4247        SELECT * FROM (((SELECT * FROM t)))
4248                      ^
4249                      This corresponds to a "wrapper" Subquery node
4250        """
4251        return all(v is None for k, v in self.args.items() if k != "this")

Whether this Subquery acts as a simple wrapper around another expression.

SELECT * FROM (((SELECT * FROM t))) ^ This corresponds to a "wrapper" Subquery node

is_star: bool
4253    @property
4254    def is_star(self) -> bool:
4255        return self.this.is_star

Checks whether an expression is a star.

output_name: str
4257    @property
4258    def output_name(self) -> str:
4259        return self.alias

Name of the output column if this expression is a selection.

If the Expression has no output name, an empty string is returned.

Example:
>>> from sqlglot import parse_one
>>> parse_one("SELECT a")sqlglot.expressions[0].output_name
'a'
>>> parse_one("SELECT b AS c")sqlglot.expressions[0].output_name
'c'
>>> parse_one("SELECT 1 + 2")sqlglot.expressions[0].output_name
''
key = 'subquery'
class TableSample(Expression):
4262class TableSample(Expression):
4263    arg_types = {
4264        "expressions": False,
4265        "method": False,
4266        "bucket_numerator": False,
4267        "bucket_denominator": False,
4268        "bucket_field": False,
4269        "percent": False,
4270        "rows": False,
4271        "size": False,
4272        "seed": False,
4273    }
arg_types = {'expressions': False, 'method': False, 'bucket_numerator': False, 'bucket_denominator': False, 'bucket_field': False, 'percent': False, 'rows': False, 'size': False, 'seed': False}
key = 'tablesample'
class Tag(Expression):
4276class Tag(Expression):
4277    """Tags are used for generating arbitrary sql like SELECT <span>x</span>."""
4278
4279    arg_types = {
4280        "this": False,
4281        "prefix": False,
4282        "postfix": False,
4283    }

Tags are used for generating arbitrary sql like SELECT x.

arg_types = {'this': False, 'prefix': False, 'postfix': False}
key = 'tag'
class Pivot(Expression):
4288class Pivot(Expression):
4289    arg_types = {
4290        "this": False,
4291        "alias": False,
4292        "expressions": False,
4293        "field": False,
4294        "unpivot": False,
4295        "using": False,
4296        "group": False,
4297        "columns": False,
4298        "include_nulls": False,
4299        "default_on_null": False,
4300        "into": False,
4301    }
4302
4303    @property
4304    def unpivot(self) -> bool:
4305        return bool(self.args.get("unpivot"))
arg_types = {'this': False, 'alias': False, 'expressions': False, 'field': False, 'unpivot': False, 'using': False, 'group': False, 'columns': False, 'include_nulls': False, 'default_on_null': False, 'into': False}
unpivot: bool
4303    @property
4304    def unpivot(self) -> bool:
4305        return bool(self.args.get("unpivot"))
key = 'pivot'
class UnpivotColumns(Expression):
4310class UnpivotColumns(Expression):
4311    arg_types = {"this": True, "expressions": True}
arg_types = {'this': True, 'expressions': True}
key = 'unpivotcolumns'
class Window(Condition):
4314class Window(Condition):
4315    arg_types = {
4316        "this": True,
4317        "partition_by": False,
4318        "order": False,
4319        "spec": False,
4320        "alias": False,
4321        "over": False,
4322        "first": False,
4323    }
arg_types = {'this': True, 'partition_by': False, 'order': False, 'spec': False, 'alias': False, 'over': False, 'first': False}
key = 'window'
class WindowSpec(Expression):
4326class WindowSpec(Expression):
4327    arg_types = {
4328        "kind": False,
4329        "start": False,
4330        "start_side": False,
4331        "end": False,
4332        "end_side": False,
4333    }
arg_types = {'kind': False, 'start': False, 'start_side': False, 'end': False, 'end_side': False}
key = 'windowspec'
class PreWhere(Expression):
4336class PreWhere(Expression):
4337    pass
key = 'prewhere'
class Where(Expression):
4340class Where(Expression):
4341    pass
key = 'where'
class Star(Expression):
4344class Star(Expression):
4345    arg_types = {"except": False, "replace": False, "rename": False}
4346
4347    @property
4348    def name(self) -> str:
4349        return "*"
4350
4351    @property
4352    def output_name(self) -> str:
4353        return self.name
arg_types = {'except': False, 'replace': False, 'rename': False}
name: str
4347    @property
4348    def name(self) -> str:
4349        return "*"
output_name: str
4351    @property
4352    def output_name(self) -> str:
4353        return self.name

Name of the output column if this expression is a selection.

If the Expression has no output name, an empty string is returned.

Example:
>>> from sqlglot import parse_one
>>> parse_one("SELECT a")sqlglot.expressions[0].output_name
'a'
>>> parse_one("SELECT b AS c")sqlglot.expressions[0].output_name
'c'
>>> parse_one("SELECT 1 + 2")sqlglot.expressions[0].output_name
''
key = 'star'
class Parameter(Condition):
4356class Parameter(Condition):
4357    arg_types = {"this": True, "expression": False}
arg_types = {'this': True, 'expression': False}
key = 'parameter'
class SessionParameter(Condition):
4360class SessionParameter(Condition):
4361    arg_types = {"this": True, "kind": False}
arg_types = {'this': True, 'kind': False}
key = 'sessionparameter'
class Placeholder(Condition):
4364class Placeholder(Condition):
4365    arg_types = {"this": False, "kind": False}
4366
4367    @property
4368    def name(self) -> str:
4369        return self.this or "?"
arg_types = {'this': False, 'kind': False}
name: str
4367    @property
4368    def name(self) -> str:
4369        return self.this or "?"
key = 'placeholder'
class Null(Condition):
4372class Null(Condition):
4373    arg_types: t.Dict[str, t.Any] = {}
4374
4375    @property
4376    def name(self) -> str:
4377        return "NULL"
4378
4379    def to_py(self) -> Lit[None]:
4380        return None
arg_types: Dict[str, Any] = {}
name: str
4375    @property
4376    def name(self) -> str:
4377        return "NULL"
def to_py(self) -> Literal[None]:
4379    def to_py(self) -> Lit[None]:
4380        return None

Returns a Python object equivalent of the SQL node.

key = 'null'
class Boolean(Condition):
4383class Boolean(Condition):
4384    def to_py(self) -> bool:
4385        return self.this
def to_py(self) -> bool:
4384    def to_py(self) -> bool:
4385        return self.this

Returns a Python object equivalent of the SQL node.

key = 'boolean'
class DataTypeParam(Expression):
4388class DataTypeParam(Expression):
4389    arg_types = {"this": True, "expression": False}
4390
4391    @property
4392    def name(self) -> str:
4393        return self.this.name
arg_types = {'this': True, 'expression': False}
name: str
4391    @property
4392    def name(self) -> str:
4393        return self.this.name
key = 'datatypeparam'
class DataType(Expression):
4398class DataType(Expression):
4399    arg_types = {
4400        "this": True,
4401        "expressions": False,
4402        "nested": False,
4403        "values": False,
4404        "prefix": False,
4405        "kind": False,
4406        "nullable": False,
4407    }
4408
4409    class Type(AutoName):
4410        ARRAY = auto()
4411        AGGREGATEFUNCTION = auto()
4412        SIMPLEAGGREGATEFUNCTION = auto()
4413        BIGDECIMAL = auto()
4414        BIGINT = auto()
4415        BIGSERIAL = auto()
4416        BINARY = auto()
4417        BIT = auto()
4418        BLOB = auto()
4419        BOOLEAN = auto()
4420        BPCHAR = auto()
4421        CHAR = auto()
4422        DATE = auto()
4423        DATE32 = auto()
4424        DATEMULTIRANGE = auto()
4425        DATERANGE = auto()
4426        DATETIME = auto()
4427        DATETIME2 = auto()
4428        DATETIME64 = auto()
4429        DECIMAL = auto()
4430        DECIMAL32 = auto()
4431        DECIMAL64 = auto()
4432        DECIMAL128 = auto()
4433        DECIMAL256 = auto()
4434        DOUBLE = auto()
4435        DYNAMIC = auto()
4436        ENUM = auto()
4437        ENUM8 = auto()
4438        ENUM16 = auto()
4439        FIXEDSTRING = auto()
4440        FLOAT = auto()
4441        GEOGRAPHY = auto()
4442        GEOMETRY = auto()
4443        POINT = auto()
4444        RING = auto()
4445        LINESTRING = auto()
4446        MULTILINESTRING = auto()
4447        POLYGON = auto()
4448        MULTIPOLYGON = auto()
4449        HLLSKETCH = auto()
4450        HSTORE = auto()
4451        IMAGE = auto()
4452        INET = auto()
4453        INT = auto()
4454        INT128 = auto()
4455        INT256 = auto()
4456        INT4MULTIRANGE = auto()
4457        INT4RANGE = auto()
4458        INT8MULTIRANGE = auto()
4459        INT8RANGE = auto()
4460        INTERVAL = auto()
4461        IPADDRESS = auto()
4462        IPPREFIX = auto()
4463        IPV4 = auto()
4464        IPV6 = auto()
4465        JSON = auto()
4466        JSONB = auto()
4467        LIST = auto()
4468        LONGBLOB = auto()
4469        LONGTEXT = auto()
4470        LOWCARDINALITY = auto()
4471        MAP = auto()
4472        MEDIUMBLOB = auto()
4473        MEDIUMINT = auto()
4474        MEDIUMTEXT = auto()
4475        MONEY = auto()
4476        NAME = auto()
4477        NCHAR = auto()
4478        NESTED = auto()
4479        NULL = auto()
4480        NUMMULTIRANGE = auto()
4481        NUMRANGE = auto()
4482        NVARCHAR = auto()
4483        OBJECT = auto()
4484        RANGE = auto()
4485        ROWVERSION = auto()
4486        SERIAL = auto()
4487        SET = auto()
4488        SMALLDATETIME = auto()
4489        SMALLINT = auto()
4490        SMALLMONEY = auto()
4491        SMALLSERIAL = auto()
4492        STRUCT = auto()
4493        SUPER = auto()
4494        TEXT = auto()
4495        TINYBLOB = auto()
4496        TINYTEXT = auto()
4497        TIME = auto()
4498        TIMETZ = auto()
4499        TIMESTAMP = auto()
4500        TIMESTAMPNTZ = auto()
4501        TIMESTAMPLTZ = auto()
4502        TIMESTAMPTZ = auto()
4503        TIMESTAMP_S = auto()
4504        TIMESTAMP_MS = auto()
4505        TIMESTAMP_NS = auto()
4506        TINYINT = auto()
4507        TSMULTIRANGE = auto()
4508        TSRANGE = auto()
4509        TSTZMULTIRANGE = auto()
4510        TSTZRANGE = auto()
4511        UBIGINT = auto()
4512        UINT = auto()
4513        UINT128 = auto()
4514        UINT256 = auto()
4515        UMEDIUMINT = auto()
4516        UDECIMAL = auto()
4517        UDOUBLE = auto()
4518        UNION = auto()
4519        UNKNOWN = auto()  # Sentinel value, useful for type annotation
4520        USERDEFINED = "USER-DEFINED"
4521        USMALLINT = auto()
4522        UTINYINT = auto()
4523        UUID = auto()
4524        VARBINARY = auto()
4525        VARCHAR = auto()
4526        VARIANT = auto()
4527        VECTOR = auto()
4528        XML = auto()
4529        YEAR = auto()
4530        TDIGEST = auto()
4531
4532    STRUCT_TYPES = {
4533        Type.NESTED,
4534        Type.OBJECT,
4535        Type.STRUCT,
4536        Type.UNION,
4537    }
4538
4539    ARRAY_TYPES = {
4540        Type.ARRAY,
4541        Type.LIST,
4542    }
4543
4544    NESTED_TYPES = {
4545        *STRUCT_TYPES,
4546        *ARRAY_TYPES,
4547        Type.MAP,
4548    }
4549
4550    TEXT_TYPES = {
4551        Type.CHAR,
4552        Type.NCHAR,
4553        Type.NVARCHAR,
4554        Type.TEXT,
4555        Type.VARCHAR,
4556        Type.NAME,
4557    }
4558
4559    SIGNED_INTEGER_TYPES = {
4560        Type.BIGINT,
4561        Type.INT,
4562        Type.INT128,
4563        Type.INT256,
4564        Type.MEDIUMINT,
4565        Type.SMALLINT,
4566        Type.TINYINT,
4567    }
4568
4569    UNSIGNED_INTEGER_TYPES = {
4570        Type.UBIGINT,
4571        Type.UINT,
4572        Type.UINT128,
4573        Type.UINT256,
4574        Type.UMEDIUMINT,
4575        Type.USMALLINT,
4576        Type.UTINYINT,
4577    }
4578
4579    INTEGER_TYPES = {
4580        *SIGNED_INTEGER_TYPES,
4581        *UNSIGNED_INTEGER_TYPES,
4582        Type.BIT,
4583    }
4584
4585    FLOAT_TYPES = {
4586        Type.DOUBLE,
4587        Type.FLOAT,
4588    }
4589
4590    REAL_TYPES = {
4591        *FLOAT_TYPES,
4592        Type.BIGDECIMAL,
4593        Type.DECIMAL,
4594        Type.DECIMAL32,
4595        Type.DECIMAL64,
4596        Type.DECIMAL128,
4597        Type.DECIMAL256,
4598        Type.MONEY,
4599        Type.SMALLMONEY,
4600        Type.UDECIMAL,
4601        Type.UDOUBLE,
4602    }
4603
4604    NUMERIC_TYPES = {
4605        *INTEGER_TYPES,
4606        *REAL_TYPES,
4607    }
4608
4609    TEMPORAL_TYPES = {
4610        Type.DATE,
4611        Type.DATE32,
4612        Type.DATETIME,
4613        Type.DATETIME2,
4614        Type.DATETIME64,
4615        Type.SMALLDATETIME,
4616        Type.TIME,
4617        Type.TIMESTAMP,
4618        Type.TIMESTAMPNTZ,
4619        Type.TIMESTAMPLTZ,
4620        Type.TIMESTAMPTZ,
4621        Type.TIMESTAMP_MS,
4622        Type.TIMESTAMP_NS,
4623        Type.TIMESTAMP_S,
4624        Type.TIMETZ,
4625    }
4626
4627    @classmethod
4628    def build(
4629        cls,
4630        dtype: DATA_TYPE,
4631        dialect: DialectType = None,
4632        udt: bool = False,
4633        copy: bool = True,
4634        **kwargs,
4635    ) -> DataType:
4636        """
4637        Constructs a DataType object.
4638
4639        Args:
4640            dtype: the data type of interest.
4641            dialect: the dialect to use for parsing `dtype`, in case it's a string.
4642            udt: when set to True, `dtype` will be used as-is if it can't be parsed into a
4643                DataType, thus creating a user-defined type.
4644            copy: whether to copy the data type.
4645            kwargs: additional arguments to pass in the constructor of DataType.
4646
4647        Returns:
4648            The constructed DataType object.
4649        """
4650        from sqlglot import parse_one
4651
4652        if isinstance(dtype, str):
4653            if dtype.upper() == "UNKNOWN":
4654                return DataType(this=DataType.Type.UNKNOWN, **kwargs)
4655
4656            try:
4657                data_type_exp = parse_one(
4658                    dtype, read=dialect, into=DataType, error_level=ErrorLevel.IGNORE
4659                )
4660            except ParseError:
4661                if udt:
4662                    return DataType(this=DataType.Type.USERDEFINED, kind=dtype, **kwargs)
4663                raise
4664        elif isinstance(dtype, DataType.Type):
4665            data_type_exp = DataType(this=dtype)
4666        elif isinstance(dtype, DataType):
4667            return maybe_copy(dtype, copy)
4668        else:
4669            raise ValueError(f"Invalid data type: {type(dtype)}. Expected str or DataType.Type")
4670
4671        return DataType(**{**data_type_exp.args, **kwargs})
4672
4673    def is_type(self, *dtypes: DATA_TYPE, check_nullable: bool = False) -> bool:
4674        """
4675        Checks whether this DataType matches one of the provided data types. Nested types or precision
4676        will be compared using "structural equivalence" semantics, so e.g. array<int> != array<float>.
4677
4678        Args:
4679            dtypes: the data types to compare this DataType to.
4680            check_nullable: whether to take the NULLABLE type constructor into account for the comparison.
4681                If false, it means that NULLABLE<INT> is equivalent to INT.
4682
4683        Returns:
4684            True, if and only if there is a type in `dtypes` which is equal to this DataType.
4685        """
4686        self_is_nullable = self.args.get("nullable")
4687        for dtype in dtypes:
4688            other_type = DataType.build(dtype, copy=False, udt=True)
4689            other_is_nullable = other_type.args.get("nullable")
4690            if (
4691                other_type.expressions
4692                or (check_nullable and (self_is_nullable or other_is_nullable))
4693                or self.this == DataType.Type.USERDEFINED
4694                or other_type.this == DataType.Type.USERDEFINED
4695            ):
4696                matches = self == other_type
4697            else:
4698                matches = self.this == other_type.this
4699
4700            if matches:
4701                return True
4702        return False
arg_types = {'this': True, 'expressions': False, 'nested': False, 'values': False, 'prefix': False, 'kind': False, 'nullable': False}
STRUCT_TYPES = {<Type.UNION: 'UNION'>, <Type.STRUCT: 'STRUCT'>, <Type.OBJECT: 'OBJECT'>, <Type.NESTED: 'NESTED'>}
ARRAY_TYPES = {<Type.LIST: 'LIST'>, <Type.ARRAY: 'ARRAY'>}
NESTED_TYPES = {<Type.LIST: 'LIST'>, <Type.STRUCT: 'STRUCT'>, <Type.ARRAY: 'ARRAY'>, <Type.OBJECT: 'OBJECT'>, <Type.MAP: 'MAP'>, <Type.UNION: 'UNION'>, <Type.NESTED: 'NESTED'>}
TEXT_TYPES = {<Type.CHAR: 'CHAR'>, <Type.NVARCHAR: 'NVARCHAR'>, <Type.NCHAR: 'NCHAR'>, <Type.VARCHAR: 'VARCHAR'>, <Type.NAME: 'NAME'>, <Type.TEXT: 'TEXT'>}
SIGNED_INTEGER_TYPES = {<Type.SMALLINT: 'SMALLINT'>, <Type.MEDIUMINT: 'MEDIUMINT'>, <Type.INT256: 'INT256'>, <Type.BIGINT: 'BIGINT'>, <Type.INT128: 'INT128'>, <Type.INT: 'INT'>, <Type.TINYINT: 'TINYINT'>}
UNSIGNED_INTEGER_TYPES = {<Type.UMEDIUMINT: 'UMEDIUMINT'>, <Type.UINT128: 'UINT128'>, <Type.UBIGINT: 'UBIGINT'>, <Type.UTINYINT: 'UTINYINT'>, <Type.USMALLINT: 'USMALLINT'>, <Type.UINT256: 'UINT256'>, <Type.UINT: 'UINT'>}
INTEGER_TYPES = {<Type.UMEDIUMINT: 'UMEDIUMINT'>, <Type.SMALLINT: 'SMALLINT'>, <Type.UINT128: 'UINT128'>, <Type.UBIGINT: 'UBIGINT'>, <Type.UTINYINT: 'UTINYINT'>, <Type.MEDIUMINT: 'MEDIUMINT'>, <Type.INT256: 'INT256'>, <Type.USMALLINT: 'USMALLINT'>, <Type.UINT256: 'UINT256'>, <Type.UINT: 'UINT'>, <Type.BIGINT: 'BIGINT'>, <Type.INT128: 'INT128'>, <Type.BIT: 'BIT'>, <Type.INT: 'INT'>, <Type.TINYINT: 'TINYINT'>}
FLOAT_TYPES = {<Type.DOUBLE: 'DOUBLE'>, <Type.FLOAT: 'FLOAT'>}
REAL_TYPES = {<Type.DECIMAL32: 'DECIMAL32'>, <Type.FLOAT: 'FLOAT'>, <Type.SMALLMONEY: 'SMALLMONEY'>, <Type.DECIMAL256: 'DECIMAL256'>, <Type.MONEY: 'MONEY'>, <Type.DECIMAL: 'DECIMAL'>, <Type.BIGDECIMAL: 'BIGDECIMAL'>, <Type.DECIMAL64: 'DECIMAL64'>, <Type.UDOUBLE: 'UDOUBLE'>, <Type.DOUBLE: 'DOUBLE'>, <Type.UDECIMAL: 'UDECIMAL'>, <Type.DECIMAL128: 'DECIMAL128'>}
NUMERIC_TYPES = {<Type.UMEDIUMINT: 'UMEDIUMINT'>, <Type.FLOAT: 'FLOAT'>, <Type.SMALLINT: 'SMALLINT'>, <Type.UINT128: 'UINT128'>, <Type.MEDIUMINT: 'MEDIUMINT'>, <Type.INT256: 'INT256'>, <Type.USMALLINT: 'USMALLINT'>, <Type.MONEY: 'MONEY'>, <Type.UINT256: 'UINT256'>, <Type.UDOUBLE: 'UDOUBLE'>, <Type.DECIMAL32: 'DECIMAL32'>, <Type.DECIMAL128: 'DECIMAL128'>, <Type.SMALLMONEY: 'SMALLMONEY'>, <Type.UBIGINT: 'UBIGINT'>, <Type.UTINYINT: 'UTINYINT'>, <Type.DECIMAL256: 'DECIMAL256'>, <Type.DECIMAL: 'DECIMAL'>, <Type.UINT: 'UINT'>, <Type.BIGDECIMAL: 'BIGDECIMAL'>, <Type.BIGINT: 'BIGINT'>, <Type.DECIMAL64: 'DECIMAL64'>, <Type.DOUBLE: 'DOUBLE'>, <Type.INT128: 'INT128'>, <Type.BIT: 'BIT'>, <Type.INT: 'INT'>, <Type.TINYINT: 'TINYINT'>, <Type.UDECIMAL: 'UDECIMAL'>}
TEMPORAL_TYPES = {<Type.TIME: 'TIME'>, <Type.TIMESTAMP: 'TIMESTAMP'>, <Type.DATETIME2: 'DATETIME2'>, <Type.TIMESTAMPNTZ: 'TIMESTAMPNTZ'>, <Type.DATE: 'DATE'>, <Type.TIMESTAMPLTZ: 'TIMESTAMPLTZ'>, <Type.SMALLDATETIME: 'SMALLDATETIME'>, <Type.TIMESTAMP_S: 'TIMESTAMP_S'>, <Type.TIMESTAMP_MS: 'TIMESTAMP_MS'>, <Type.DATE32: 'DATE32'>, <Type.DATETIME64: 'DATETIME64'>, <Type.TIMESTAMPTZ: 'TIMESTAMPTZ'>, <Type.TIMETZ: 'TIMETZ'>, <Type.TIMESTAMP_NS: 'TIMESTAMP_NS'>, <Type.DATETIME: 'DATETIME'>}
@classmethod
def build( cls, dtype: Union[str, DataType, DataType.Type], dialect: Union[str, sqlglot.dialects.Dialect, Type[sqlglot.dialects.Dialect], NoneType] = None, udt: bool = False, copy: bool = True, **kwargs) -> DataType:
4627    @classmethod
4628    def build(
4629        cls,
4630        dtype: DATA_TYPE,
4631        dialect: DialectType = None,
4632        udt: bool = False,
4633        copy: bool = True,
4634        **kwargs,
4635    ) -> DataType:
4636        """
4637        Constructs a DataType object.
4638
4639        Args:
4640            dtype: the data type of interest.
4641            dialect: the dialect to use for parsing `dtype`, in case it's a string.
4642            udt: when set to True, `dtype` will be used as-is if it can't be parsed into a
4643                DataType, thus creating a user-defined type.
4644            copy: whether to copy the data type.
4645            kwargs: additional arguments to pass in the constructor of DataType.
4646
4647        Returns:
4648            The constructed DataType object.
4649        """
4650        from sqlglot import parse_one
4651
4652        if isinstance(dtype, str):
4653            if dtype.upper() == "UNKNOWN":
4654                return DataType(this=DataType.Type.UNKNOWN, **kwargs)
4655
4656            try:
4657                data_type_exp = parse_one(
4658                    dtype, read=dialect, into=DataType, error_level=ErrorLevel.IGNORE
4659                )
4660            except ParseError:
4661                if udt:
4662                    return DataType(this=DataType.Type.USERDEFINED, kind=dtype, **kwargs)
4663                raise
4664        elif isinstance(dtype, DataType.Type):
4665            data_type_exp = DataType(this=dtype)
4666        elif isinstance(dtype, DataType):
4667            return maybe_copy(dtype, copy)
4668        else:
4669            raise ValueError(f"Invalid data type: {type(dtype)}. Expected str or DataType.Type")
4670
4671        return DataType(**{**data_type_exp.args, **kwargs})

Constructs a DataType object.

Arguments:
  • dtype: the data type of interest.
  • dialect: the dialect to use for parsing dtype, in case it's a string.
  • udt: when set to True, dtype will be used as-is if it can't be parsed into a DataType, thus creating a user-defined type.
  • copy: whether to copy the data type.
  • kwargs: additional arguments to pass in the constructor of DataType.
Returns:

The constructed DataType object.

def is_type( self, *dtypes: Union[str, DataType, DataType.Type], check_nullable: bool = False) -> bool:
4673    def is_type(self, *dtypes: DATA_TYPE, check_nullable: bool = False) -> bool:
4674        """
4675        Checks whether this DataType matches one of the provided data types. Nested types or precision
4676        will be compared using "structural equivalence" semantics, so e.g. array<int> != array<float>.
4677
4678        Args:
4679            dtypes: the data types to compare this DataType to.
4680            check_nullable: whether to take the NULLABLE type constructor into account for the comparison.
4681                If false, it means that NULLABLE<INT> is equivalent to INT.
4682
4683        Returns:
4684            True, if and only if there is a type in `dtypes` which is equal to this DataType.
4685        """
4686        self_is_nullable = self.args.get("nullable")
4687        for dtype in dtypes:
4688            other_type = DataType.build(dtype, copy=False, udt=True)
4689            other_is_nullable = other_type.args.get("nullable")
4690            if (
4691                other_type.expressions
4692                or (check_nullable and (self_is_nullable or other_is_nullable))
4693                or self.this == DataType.Type.USERDEFINED
4694                or other_type.this == DataType.Type.USERDEFINED
4695            ):
4696                matches = self == other_type
4697            else:
4698                matches = self.this == other_type.this
4699
4700            if matches:
4701                return True
4702        return False

Checks whether this DataType matches one of the provided data types. Nested types or precision will be compared using "structural equivalence" semantics, so e.g. array != array.

Arguments:
  • dtypes: the data types to compare this DataType to.
  • check_nullable: whether to take the NULLABLE type constructor into account for the comparison. If false, it means that NULLABLE is equivalent to INT.
Returns:

True, if and only if there is a type in dtypes which is equal to this DataType.

key = 'datatype'
class DataType.Type(sqlglot.helper.AutoName):
4409    class Type(AutoName):
4410        ARRAY = auto()
4411        AGGREGATEFUNCTION = auto()
4412        SIMPLEAGGREGATEFUNCTION = auto()
4413        BIGDECIMAL = auto()
4414        BIGINT = auto()
4415        BIGSERIAL = auto()
4416        BINARY = auto()
4417        BIT = auto()
4418        BLOB = auto()
4419        BOOLEAN = auto()
4420        BPCHAR = auto()
4421        CHAR = auto()
4422        DATE = auto()
4423        DATE32 = auto()
4424        DATEMULTIRANGE = auto()
4425        DATERANGE = auto()
4426        DATETIME = auto()
4427        DATETIME2 = auto()
4428        DATETIME64 = auto()
4429        DECIMAL = auto()
4430        DECIMAL32 = auto()
4431        DECIMAL64 = auto()
4432        DECIMAL128 = auto()
4433        DECIMAL256 = auto()
4434        DOUBLE = auto()
4435        DYNAMIC = auto()
4436        ENUM = auto()
4437        ENUM8 = auto()
4438        ENUM16 = auto()
4439        FIXEDSTRING = auto()
4440        FLOAT = auto()
4441        GEOGRAPHY = auto()
4442        GEOMETRY = auto()
4443        POINT = auto()
4444        RING = auto()
4445        LINESTRING = auto()
4446        MULTILINESTRING = auto()
4447        POLYGON = auto()
4448        MULTIPOLYGON = auto()
4449        HLLSKETCH = auto()
4450        HSTORE = auto()
4451        IMAGE = auto()
4452        INET = auto()
4453        INT = auto()
4454        INT128 = auto()
4455        INT256 = auto()
4456        INT4MULTIRANGE = auto()
4457        INT4RANGE = auto()
4458        INT8MULTIRANGE = auto()
4459        INT8RANGE = auto()
4460        INTERVAL = auto()
4461        IPADDRESS = auto()
4462        IPPREFIX = auto()
4463        IPV4 = auto()
4464        IPV6 = auto()
4465        JSON = auto()
4466        JSONB = auto()
4467        LIST = auto()
4468        LONGBLOB = auto()
4469        LONGTEXT = auto()
4470        LOWCARDINALITY = auto()
4471        MAP = auto()
4472        MEDIUMBLOB = auto()
4473        MEDIUMINT = auto()
4474        MEDIUMTEXT = auto()
4475        MONEY = auto()
4476        NAME = auto()
4477        NCHAR = auto()
4478        NESTED = auto()
4479        NULL = auto()
4480        NUMMULTIRANGE = auto()
4481        NUMRANGE = auto()
4482        NVARCHAR = auto()
4483        OBJECT = auto()
4484        RANGE = auto()
4485        ROWVERSION = auto()
4486        SERIAL = auto()
4487        SET = auto()
4488        SMALLDATETIME = auto()
4489        SMALLINT = auto()
4490        SMALLMONEY = auto()
4491        SMALLSERIAL = auto()
4492        STRUCT = auto()
4493        SUPER = auto()
4494        TEXT = auto()
4495        TINYBLOB = auto()
4496        TINYTEXT = auto()
4497        TIME = auto()
4498        TIMETZ = auto()
4499        TIMESTAMP = auto()
4500        TIMESTAMPNTZ = auto()
4501        TIMESTAMPLTZ = auto()
4502        TIMESTAMPTZ = auto()
4503        TIMESTAMP_S = auto()
4504        TIMESTAMP_MS = auto()
4505        TIMESTAMP_NS = auto()
4506        TINYINT = auto()
4507        TSMULTIRANGE = auto()
4508        TSRANGE = auto()
4509        TSTZMULTIRANGE = auto()
4510        TSTZRANGE = auto()
4511        UBIGINT = auto()
4512        UINT = auto()
4513        UINT128 = auto()
4514        UINT256 = auto()
4515        UMEDIUMINT = auto()
4516        UDECIMAL = auto()
4517        UDOUBLE = auto()
4518        UNION = auto()
4519        UNKNOWN = auto()  # Sentinel value, useful for type annotation
4520        USERDEFINED = "USER-DEFINED"
4521        USMALLINT = auto()
4522        UTINYINT = auto()
4523        UUID = auto()
4524        VARBINARY = auto()
4525        VARCHAR = auto()
4526        VARIANT = auto()
4527        VECTOR = auto()
4528        XML = auto()
4529        YEAR = auto()
4530        TDIGEST = auto()

An enumeration.

ARRAY = <Type.ARRAY: 'ARRAY'>
AGGREGATEFUNCTION = <Type.AGGREGATEFUNCTION: 'AGGREGATEFUNCTION'>
SIMPLEAGGREGATEFUNCTION = <Type.SIMPLEAGGREGATEFUNCTION: 'SIMPLEAGGREGATEFUNCTION'>
BIGDECIMAL = <Type.BIGDECIMAL: 'BIGDECIMAL'>
BIGINT = <Type.BIGINT: 'BIGINT'>
BIGSERIAL = <Type.BIGSERIAL: 'BIGSERIAL'>
BINARY = <Type.BINARY: 'BINARY'>
BIT = <Type.BIT: 'BIT'>
BLOB = <Type.BLOB: 'BLOB'>
BOOLEAN = <Type.BOOLEAN: 'BOOLEAN'>
BPCHAR = <Type.BPCHAR: 'BPCHAR'>
CHAR = <Type.CHAR: 'CHAR'>
DATE = <Type.DATE: 'DATE'>
DATE32 = <Type.DATE32: 'DATE32'>
DATEMULTIRANGE = <Type.DATEMULTIRANGE: 'DATEMULTIRANGE'>
DATERANGE = <Type.DATERANGE: 'DATERANGE'>
DATETIME = <Type.DATETIME: 'DATETIME'>
DATETIME2 = <Type.DATETIME2: 'DATETIME2'>
DATETIME64 = <Type.DATETIME64: 'DATETIME64'>
DECIMAL = <Type.DECIMAL: 'DECIMAL'>
DECIMAL32 = <Type.DECIMAL32: 'DECIMAL32'>
DECIMAL64 = <Type.DECIMAL64: 'DECIMAL64'>
DECIMAL128 = <Type.DECIMAL128: 'DECIMAL128'>
DECIMAL256 = <Type.DECIMAL256: 'DECIMAL256'>
DOUBLE = <Type.DOUBLE: 'DOUBLE'>
DYNAMIC = <Type.DYNAMIC: 'DYNAMIC'>
ENUM = <Type.ENUM: 'ENUM'>
ENUM8 = <Type.ENUM8: 'ENUM8'>
ENUM16 = <Type.ENUM16: 'ENUM16'>
FIXEDSTRING = <Type.FIXEDSTRING: 'FIXEDSTRING'>
FLOAT = <Type.FLOAT: 'FLOAT'>
GEOGRAPHY = <Type.GEOGRAPHY: 'GEOGRAPHY'>
GEOMETRY = <Type.GEOMETRY: 'GEOMETRY'>
POINT = <Type.POINT: 'POINT'>
RING = <Type.RING: 'RING'>
LINESTRING = <Type.LINESTRING: 'LINESTRING'>
MULTILINESTRING = <Type.MULTILINESTRING: 'MULTILINESTRING'>
POLYGON = <Type.POLYGON: 'POLYGON'>
MULTIPOLYGON = <Type.MULTIPOLYGON: 'MULTIPOLYGON'>
HLLSKETCH = <Type.HLLSKETCH: 'HLLSKETCH'>
HSTORE = <Type.HSTORE: 'HSTORE'>
IMAGE = <Type.IMAGE: 'IMAGE'>
INET = <Type.INET: 'INET'>
INT = <Type.INT: 'INT'>
INT128 = <Type.INT128: 'INT128'>
INT256 = <Type.INT256: 'INT256'>
INT4MULTIRANGE = <Type.INT4MULTIRANGE: 'INT4MULTIRANGE'>
INT4RANGE = <Type.INT4RANGE: 'INT4RANGE'>
INT8MULTIRANGE = <Type.INT8MULTIRANGE: 'INT8MULTIRANGE'>
INT8RANGE = <Type.INT8RANGE: 'INT8RANGE'>
INTERVAL = <Type.INTERVAL: 'INTERVAL'>
IPADDRESS = <Type.IPADDRESS: 'IPADDRESS'>
IPPREFIX = <Type.IPPREFIX: 'IPPREFIX'>
IPV4 = <Type.IPV4: 'IPV4'>
IPV6 = <Type.IPV6: 'IPV6'>
JSON = <Type.JSON: 'JSON'>
JSONB = <Type.JSONB: 'JSONB'>
LIST = <Type.LIST: 'LIST'>
LONGBLOB = <Type.LONGBLOB: 'LONGBLOB'>
LONGTEXT = <Type.LONGTEXT: 'LONGTEXT'>
LOWCARDINALITY = <Type.LOWCARDINALITY: 'LOWCARDINALITY'>
MAP = <Type.MAP: 'MAP'>
MEDIUMBLOB = <Type.MEDIUMBLOB: 'MEDIUMBLOB'>
MEDIUMINT = <Type.MEDIUMINT: 'MEDIUMINT'>
MEDIUMTEXT = <Type.MEDIUMTEXT: 'MEDIUMTEXT'>
MONEY = <Type.MONEY: 'MONEY'>
NAME = <Type.NAME: 'NAME'>
NCHAR = <Type.NCHAR: 'NCHAR'>
NESTED = <Type.NESTED: 'NESTED'>
NULL = <Type.NULL: 'NULL'>
NUMMULTIRANGE = <Type.NUMMULTIRANGE: 'NUMMULTIRANGE'>
NUMRANGE = <Type.NUMRANGE: 'NUMRANGE'>
NVARCHAR = <Type.NVARCHAR: 'NVARCHAR'>
OBJECT = <Type.OBJECT: 'OBJECT'>
RANGE = <Type.RANGE: 'RANGE'>
ROWVERSION = <Type.ROWVERSION: 'ROWVERSION'>
SERIAL = <Type.SERIAL: 'SERIAL'>
SET = <Type.SET: 'SET'>
SMALLDATETIME = <Type.SMALLDATETIME: 'SMALLDATETIME'>
SMALLINT = <Type.SMALLINT: 'SMALLINT'>
SMALLMONEY = <Type.SMALLMONEY: 'SMALLMONEY'>
SMALLSERIAL = <Type.SMALLSERIAL: 'SMALLSERIAL'>
STRUCT = <Type.STRUCT: 'STRUCT'>
SUPER = <Type.SUPER: 'SUPER'>
TEXT = <Type.TEXT: 'TEXT'>
TINYBLOB = <Type.TINYBLOB: 'TINYBLOB'>
TINYTEXT = <Type.TINYTEXT: 'TINYTEXT'>
TIME = <Type.TIME: 'TIME'>
TIMETZ = <Type.TIMETZ: 'TIMETZ'>
TIMESTAMP = <Type.TIMESTAMP: 'TIMESTAMP'>
TIMESTAMPNTZ = <Type.TIMESTAMPNTZ: 'TIMESTAMPNTZ'>
TIMESTAMPLTZ = <Type.TIMESTAMPLTZ: 'TIMESTAMPLTZ'>
TIMESTAMPTZ = <Type.TIMESTAMPTZ: 'TIMESTAMPTZ'>
TIMESTAMP_S = <Type.TIMESTAMP_S: 'TIMESTAMP_S'>
TIMESTAMP_MS = <Type.TIMESTAMP_MS: 'TIMESTAMP_MS'>
TIMESTAMP_NS = <Type.TIMESTAMP_NS: 'TIMESTAMP_NS'>
TINYINT = <Type.TINYINT: 'TINYINT'>
TSMULTIRANGE = <Type.TSMULTIRANGE: 'TSMULTIRANGE'>
TSRANGE = <Type.TSRANGE: 'TSRANGE'>
TSTZMULTIRANGE = <Type.TSTZMULTIRANGE: 'TSTZMULTIRANGE'>
TSTZRANGE = <Type.TSTZRANGE: 'TSTZRANGE'>
UBIGINT = <Type.UBIGINT: 'UBIGINT'>
UINT = <Type.UINT: 'UINT'>
UINT128 = <Type.UINT128: 'UINT128'>
UINT256 = <Type.UINT256: 'UINT256'>
UMEDIUMINT = <Type.UMEDIUMINT: 'UMEDIUMINT'>
UDECIMAL = <Type.UDECIMAL: 'UDECIMAL'>
UDOUBLE = <Type.UDOUBLE: 'UDOUBLE'>
UNION = <Type.UNION: 'UNION'>
UNKNOWN = <Type.UNKNOWN: 'UNKNOWN'>
USERDEFINED = <Type.USERDEFINED: 'USER-DEFINED'>
USMALLINT = <Type.USMALLINT: 'USMALLINT'>
UTINYINT = <Type.UTINYINT: 'UTINYINT'>
UUID = <Type.UUID: 'UUID'>
VARBINARY = <Type.VARBINARY: 'VARBINARY'>
VARCHAR = <Type.VARCHAR: 'VARCHAR'>
VARIANT = <Type.VARIANT: 'VARIANT'>
VECTOR = <Type.VECTOR: 'VECTOR'>
XML = <Type.XML: 'XML'>
YEAR = <Type.YEAR: 'YEAR'>
TDIGEST = <Type.TDIGEST: 'TDIGEST'>
DATA_TYPE = typing.Union[str, DataType, DataType.Type]
class PseudoType(DataType):
4709class PseudoType(DataType):
4710    arg_types = {"this": True}
arg_types = {'this': True}
key = 'pseudotype'
class ObjectIdentifier(DataType):
4714class ObjectIdentifier(DataType):
4715    arg_types = {"this": True}
arg_types = {'this': True}
key = 'objectidentifier'
class SubqueryPredicate(Predicate):
4719class SubqueryPredicate(Predicate):
4720    pass
key = 'subquerypredicate'
class All(SubqueryPredicate):
4723class All(SubqueryPredicate):
4724    pass
key = 'all'
class Any(SubqueryPredicate):
4727class Any(SubqueryPredicate):
4728    pass
key = 'any'
class Command(Expression):
4733class Command(Expression):
4734    arg_types = {"this": True, "expression": False}
arg_types = {'this': True, 'expression': False}
key = 'command'
class Transaction(Expression):
4737class Transaction(Expression):
4738    arg_types = {"this": False, "modes": False, "mark": False}
arg_types = {'this': False, 'modes': False, 'mark': False}
key = 'transaction'
class Commit(Expression):
4741class Commit(Expression):
4742    arg_types = {"chain": False, "this": False, "durability": False}
arg_types = {'chain': False, 'this': False, 'durability': False}
key = 'commit'
class Rollback(Expression):
4745class Rollback(Expression):
4746    arg_types = {"savepoint": False, "this": False}
arg_types = {'savepoint': False, 'this': False}
key = 'rollback'
class Alter(Expression):
4749class Alter(Expression):
4750    arg_types = {
4751        "this": True,
4752        "kind": True,
4753        "actions": True,
4754        "exists": False,
4755        "only": False,
4756        "options": False,
4757        "cluster": False,
4758        "not_valid": False,
4759    }
4760
4761    @property
4762    def kind(self) -> t.Optional[str]:
4763        kind = self.args.get("kind")
4764        return kind and kind.upper()
4765
4766    @property
4767    def actions(self) -> t.List[Expression]:
4768        return self.args.get("actions") or []
arg_types = {'this': True, 'kind': True, 'actions': True, 'exists': False, 'only': False, 'options': False, 'cluster': False, 'not_valid': False}
kind: Optional[str]
4761    @property
4762    def kind(self) -> t.Optional[str]:
4763        kind = self.args.get("kind")
4764        return kind and kind.upper()
actions: List[Expression]
4766    @property
4767    def actions(self) -> t.List[Expression]:
4768        return self.args.get("actions") or []
key = 'alter'
class Analyze(Expression):
4771class Analyze(Expression):
4772    arg_types = {
4773        "kind": False,
4774        "this": False,
4775        "options": False,
4776        "mode": False,
4777        "partition": False,
4778        "expression": False,
4779        "properties": False,
4780    }
arg_types = {'kind': False, 'this': False, 'options': False, 'mode': False, 'partition': False, 'expression': False, 'properties': False}
key = 'analyze'
class AnalyzeStatistics(Expression):
4783class AnalyzeStatistics(Expression):
4784    arg_types = {
4785        "kind": True,
4786        "option": False,
4787        "this": False,
4788        "expressions": False,
4789    }
arg_types = {'kind': True, 'option': False, 'this': False, 'expressions': False}
key = 'analyzestatistics'
class AnalyzeHistogram(Expression):
4792class AnalyzeHistogram(Expression):
4793    arg_types = {
4794        "this": True,
4795        "expressions": True,
4796        "expression": False,
4797        "update_options": False,
4798    }
arg_types = {'this': True, 'expressions': True, 'expression': False, 'update_options': False}
key = 'analyzehistogram'
class AnalyzeSample(Expression):
4801class AnalyzeSample(Expression):
4802    arg_types = {"kind": True, "sample": True}
arg_types = {'kind': True, 'sample': True}
key = 'analyzesample'
class AnalyzeListChainedRows(Expression):
4805class AnalyzeListChainedRows(Expression):
4806    arg_types = {"expression": False}
arg_types = {'expression': False}
key = 'analyzelistchainedrows'
class AnalyzeDelete(Expression):
4809class AnalyzeDelete(Expression):
4810    arg_types = {"kind": False}
arg_types = {'kind': False}
key = 'analyzedelete'
class AnalyzeWith(Expression):
4813class AnalyzeWith(Expression):
4814    arg_types = {"expressions": True}
arg_types = {'expressions': True}
key = 'analyzewith'
class AnalyzeValidate(Expression):
4817class AnalyzeValidate(Expression):
4818    arg_types = {
4819        "kind": True,
4820        "this": False,
4821        "expression": False,
4822    }
arg_types = {'kind': True, 'this': False, 'expression': False}
key = 'analyzevalidate'
class AnalyzeColumns(Expression):
4825class AnalyzeColumns(Expression):
4826    pass
key = 'analyzecolumns'
class UsingData(Expression):
4829class UsingData(Expression):
4830    pass
key = 'usingdata'
class AddConstraint(Expression):
4833class AddConstraint(Expression):
4834    arg_types = {"expressions": True}
arg_types = {'expressions': True}
key = 'addconstraint'
class AttachOption(Expression):
4837class AttachOption(Expression):
4838    arg_types = {"this": True, "expression": False}
arg_types = {'this': True, 'expression': False}
key = 'attachoption'
class DropPartition(Expression):
4841class DropPartition(Expression):
4842    arg_types = {"expressions": True, "exists": False}
arg_types = {'expressions': True, 'exists': False}
key = 'droppartition'
class ReplacePartition(Expression):
4846class ReplacePartition(Expression):
4847    arg_types = {"expression": True, "source": True}
arg_types = {'expression': True, 'source': True}
key = 'replacepartition'
class Binary(Condition):
4851class Binary(Condition):
4852    arg_types = {"this": True, "expression": True}
4853
4854    @property
4855    def left(self) -> Expression:
4856        return self.this
4857
4858    @property
4859    def right(self) -> Expression:
4860        return self.expression
arg_types = {'this': True, 'expression': True}
left: Expression
4854    @property
4855    def left(self) -> Expression:
4856        return self.this
right: Expression
4858    @property
4859    def right(self) -> Expression:
4860        return self.expression
key = 'binary'
class Add(Binary):
4863class Add(Binary):
4864    pass
key = 'add'
class Connector(Binary):
4867class Connector(Binary):
4868    pass
key = 'connector'
class BitwiseAnd(Binary):
4871class BitwiseAnd(Binary):
4872    pass
key = 'bitwiseand'
class BitwiseLeftShift(Binary):
4875class BitwiseLeftShift(Binary):
4876    pass
key = 'bitwiseleftshift'
class BitwiseOr(Binary):
4879class BitwiseOr(Binary):
4880    pass
key = 'bitwiseor'
class BitwiseRightShift(Binary):
4883class BitwiseRightShift(Binary):
4884    pass
key = 'bitwiserightshift'
class BitwiseXor(Binary):
4887class BitwiseXor(Binary):
4888    pass
key = 'bitwisexor'
class Div(Binary):
4891class Div(Binary):
4892    arg_types = {"this": True, "expression": True, "typed": False, "safe": False}
arg_types = {'this': True, 'expression': True, 'typed': False, 'safe': False}
key = 'div'
class Overlaps(Binary):
4895class Overlaps(Binary):
4896    pass
key = 'overlaps'
class Dot(Binary):
4899class Dot(Binary):
4900    @property
4901    def is_star(self) -> bool:
4902        return self.expression.is_star
4903
4904    @property
4905    def name(self) -> str:
4906        return self.expression.name
4907
4908    @property
4909    def output_name(self) -> str:
4910        return self.name
4911
4912    @classmethod
4913    def build(self, expressions: t.Sequence[Expression]) -> Dot:
4914        """Build a Dot object with a sequence of expressions."""
4915        if len(expressions) < 2:
4916            raise ValueError("Dot requires >= 2 expressions.")
4917
4918        return t.cast(Dot, reduce(lambda x, y: Dot(this=x, expression=y), expressions))
4919
4920    @property
4921    def parts(self) -> t.List[Expression]:
4922        """Return the parts of a table / column in order catalog, db, table."""
4923        this, *parts = self.flatten()
4924
4925        parts.reverse()
4926
4927        for arg in COLUMN_PARTS:
4928            part = this.args.get(arg)
4929
4930            if isinstance(part, Expression):
4931                parts.append(part)
4932
4933        parts.reverse()
4934        return parts
is_star: bool
4900    @property
4901    def is_star(self) -> bool:
4902        return self.expression.is_star

Checks whether an expression is a star.

name: str
4904    @property
4905    def name(self) -> str:
4906        return self.expression.name
output_name: str
4908    @property
4909    def output_name(self) -> str:
4910        return self.name

Name of the output column if this expression is a selection.

If the Expression has no output name, an empty string is returned.

Example:
>>> from sqlglot import parse_one
>>> parse_one("SELECT a")sqlglot.expressions[0].output_name
'a'
>>> parse_one("SELECT b AS c")sqlglot.expressions[0].output_name
'c'
>>> parse_one("SELECT 1 + 2")sqlglot.expressions[0].output_name
''
@classmethod
def build( self, expressions: Sequence[Expression]) -> Dot:
4912    @classmethod
4913    def build(self, expressions: t.Sequence[Expression]) -> Dot:
4914        """Build a Dot object with a sequence of expressions."""
4915        if len(expressions) < 2:
4916            raise ValueError("Dot requires >= 2 expressions.")
4917
4918        return t.cast(Dot, reduce(lambda x, y: Dot(this=x, expression=y), expressions))

Build a Dot object with a sequence of expressions.

parts: List[Expression]
4920    @property
4921    def parts(self) -> t.List[Expression]:
4922        """Return the parts of a table / column in order catalog, db, table."""
4923        this, *parts = self.flatten()
4924
4925        parts.reverse()
4926
4927        for arg in COLUMN_PARTS:
4928            part = this.args.get(arg)
4929
4930            if isinstance(part, Expression):
4931                parts.append(part)
4932
4933        parts.reverse()
4934        return parts

Return the parts of a table / column in order catalog, db, table.

key = 'dot'
class DPipe(Binary):
4937class DPipe(Binary):
4938    arg_types = {"this": True, "expression": True, "safe": False}
arg_types = {'this': True, 'expression': True, 'safe': False}
key = 'dpipe'
class EQ(Binary, Predicate):
4941class EQ(Binary, Predicate):
4942    pass
key = 'eq'
class NullSafeEQ(Binary, Predicate):
4945class NullSafeEQ(Binary, Predicate):
4946    pass
key = 'nullsafeeq'
class NullSafeNEQ(Binary, Predicate):
4949class NullSafeNEQ(Binary, Predicate):
4950    pass
key = 'nullsafeneq'
class PropertyEQ(Binary):
4954class PropertyEQ(Binary):
4955    pass
key = 'propertyeq'
class Distance(Binary):
4958class Distance(Binary):
4959    pass
key = 'distance'
class Escape(Binary):
4962class Escape(Binary):
4963    pass
key = 'escape'
class Glob(Binary, Predicate):
4966class Glob(Binary, Predicate):
4967    pass
key = 'glob'
class GT(Binary, Predicate):
4970class GT(Binary, Predicate):
4971    pass
key = 'gt'
class GTE(Binary, Predicate):
4974class GTE(Binary, Predicate):
4975    pass
key = 'gte'
class ILike(Binary, Predicate):
4978class ILike(Binary, Predicate):
4979    pass
key = 'ilike'
class ILikeAny(Binary, Predicate):
4982class ILikeAny(Binary, Predicate):
4983    pass
key = 'ilikeany'
class IntDiv(Binary):
4986class IntDiv(Binary):
4987    pass
key = 'intdiv'
class Is(Binary, Predicate):
4990class Is(Binary, Predicate):
4991    pass
key = 'is'
class Kwarg(Binary):
4994class Kwarg(Binary):
4995    """Kwarg in special functions like func(kwarg => y)."""

Kwarg in special functions like func(kwarg => y).

key = 'kwarg'
class Like(Binary, Predicate):
4998class Like(Binary, Predicate):
4999    pass
key = 'like'
class LikeAny(Binary, Predicate):
5002class LikeAny(Binary, Predicate):
5003    pass
key = 'likeany'
class LT(Binary, Predicate):
5006class LT(Binary, Predicate):
5007    pass
key = 'lt'
class LTE(Binary, Predicate):
5010class LTE(Binary, Predicate):
5011    pass
key = 'lte'
class Mod(Binary):
5014class Mod(Binary):
5015    pass
key = 'mod'
class Mul(Binary):
5018class Mul(Binary):
5019    pass
key = 'mul'
class NEQ(Binary, Predicate):
5022class NEQ(Binary, Predicate):
5023    pass
key = 'neq'
class Operator(Binary):
5027class Operator(Binary):
5028    arg_types = {"this": True, "operator": True, "expression": True}
arg_types = {'this': True, 'operator': True, 'expression': True}
key = 'operator'
class SimilarTo(Binary, Predicate):
5031class SimilarTo(Binary, Predicate):
5032    pass
key = 'similarto'
class Slice(Binary):
5035class Slice(Binary):
5036    arg_types = {"this": False, "expression": False}
arg_types = {'this': False, 'expression': False}
key = 'slice'
class Sub(Binary):
5039class Sub(Binary):
5040    pass
key = 'sub'
class Unary(Condition):
5045class Unary(Condition):
5046    pass
key = 'unary'
class BitwiseNot(Unary):
5049class BitwiseNot(Unary):
5050    pass
key = 'bitwisenot'
class Not(Unary):
5053class Not(Unary):
5054    pass
key = 'not'
class Paren(Unary):
5057class Paren(Unary):
5058    @property
5059    def output_name(self) -> str:
5060        return self.this.name
output_name: str
5058    @property
5059    def output_name(self) -> str:
5060        return self.this.name

Name of the output column if this expression is a selection.

If the Expression has no output name, an empty string is returned.

Example:
>>> from sqlglot import parse_one
>>> parse_one("SELECT a")sqlglot.expressions[0].output_name
'a'
>>> parse_one("SELECT b AS c")sqlglot.expressions[0].output_name
'c'
>>> parse_one("SELECT 1 + 2")sqlglot.expressions[0].output_name
''
key = 'paren'
class Neg(Unary):
5063class Neg(Unary):
5064    def to_py(self) -> int | Decimal:
5065        if self.is_number:
5066            return self.this.to_py() * -1
5067        return super().to_py()
def to_py(self) -> int | decimal.Decimal:
5064    def to_py(self) -> int | Decimal:
5065        if self.is_number:
5066            return self.this.to_py() * -1
5067        return super().to_py()

Returns a Python object equivalent of the SQL node.

key = 'neg'
class Alias(Expression):
5070class Alias(Expression):
5071    arg_types = {"this": True, "alias": False}
5072
5073    @property
5074    def output_name(self) -> str:
5075        return self.alias
arg_types = {'this': True, 'alias': False}
output_name: str
5073    @property
5074    def output_name(self) -> str:
5075        return self.alias

Name of the output column if this expression is a selection.

If the Expression has no output name, an empty string is returned.

Example:
>>> from sqlglot import parse_one
>>> parse_one("SELECT a")sqlglot.expressions[0].output_name
'a'
>>> parse_one("SELECT b AS c")sqlglot.expressions[0].output_name
'c'
>>> parse_one("SELECT 1 + 2")sqlglot.expressions[0].output_name
''
key = 'alias'
class PivotAlias(Alias):
5080class PivotAlias(Alias):
5081    pass
key = 'pivotalias'
class PivotAny(Expression):
5086class PivotAny(Expression):
5087    arg_types = {"this": False}
arg_types = {'this': False}
key = 'pivotany'
class Aliases(Expression):
5090class Aliases(Expression):
5091    arg_types = {"this": True, "expressions": True}
5092
5093    @property
5094    def aliases(self):
5095        return self.expressions
arg_types = {'this': True, 'expressions': True}
aliases
5093    @property
5094    def aliases(self):
5095        return self.expressions
key = 'aliases'
class AtIndex(Expression):
5099class AtIndex(Expression):
5100    arg_types = {"this": True, "expression": True}
arg_types = {'this': True, 'expression': True}
key = 'atindex'
class AtTimeZone(Expression):
5103class AtTimeZone(Expression):
5104    arg_types = {"this": True, "zone": True}
arg_types = {'this': True, 'zone': True}
key = 'attimezone'
class FromTimeZone(Expression):
5107class FromTimeZone(Expression):
5108    arg_types = {"this": True, "zone": True}
arg_types = {'this': True, 'zone': True}
key = 'fromtimezone'
class Between(Predicate):
5111class Between(Predicate):
5112    arg_types = {"this": True, "low": True, "high": True}
arg_types = {'this': True, 'low': True, 'high': True}
key = 'between'
class Bracket(Condition):
5115class Bracket(Condition):
5116    # https://cloud.google.com/bigquery/docs/reference/standard-sql/operators#array_subscript_operator
5117    arg_types = {
5118        "this": True,
5119        "expressions": True,
5120        "offset": False,
5121        "safe": False,
5122        "returns_list_for_maps": False,
5123    }
5124
5125    @property
5126    def output_name(self) -> str:
5127        if len(self.expressions) == 1:
5128            return self.expressions[0].output_name
5129
5130        return super().output_name
arg_types = {'this': True, 'expressions': True, 'offset': False, 'safe': False, 'returns_list_for_maps': False}
output_name: str
5125    @property
5126    def output_name(self) -> str:
5127        if len(self.expressions) == 1:
5128            return self.expressions[0].output_name
5129
5130        return super().output_name

Name of the output column if this expression is a selection.

If the Expression has no output name, an empty string is returned.

Example:
>>> from sqlglot import parse_one
>>> parse_one("SELECT a")sqlglot.expressions[0].output_name
'a'
>>> parse_one("SELECT b AS c")sqlglot.expressions[0].output_name
'c'
>>> parse_one("SELECT 1 + 2")sqlglot.expressions[0].output_name
''
key = 'bracket'
class Distinct(Expression):
5133class Distinct(Expression):
5134    arg_types = {"expressions": False, "on": False}
arg_types = {'expressions': False, 'on': False}
key = 'distinct'
class In(Predicate):
5137class In(Predicate):
5138    arg_types = {
5139        "this": True,
5140        "expressions": False,
5141        "query": False,
5142        "unnest": False,
5143        "field": False,
5144        "is_global": False,
5145    }
arg_types = {'this': True, 'expressions': False, 'query': False, 'unnest': False, 'field': False, 'is_global': False}
key = 'in'
class ForIn(Expression):
5149class ForIn(Expression):
5150    arg_types = {"this": True, "expression": True}
arg_types = {'this': True, 'expression': True}
key = 'forin'
class TimeUnit(Expression):
5153class TimeUnit(Expression):
5154    """Automatically converts unit arg into a var."""
5155
5156    arg_types = {"unit": False}
5157
5158    UNABBREVIATED_UNIT_NAME = {
5159        "D": "DAY",
5160        "H": "HOUR",
5161        "M": "MINUTE",
5162        "MS": "MILLISECOND",
5163        "NS": "NANOSECOND",
5164        "Q": "QUARTER",
5165        "S": "SECOND",
5166        "US": "MICROSECOND",
5167        "W": "WEEK",
5168        "Y": "YEAR",
5169    }
5170
5171    VAR_LIKE = (Column, Literal, Var)
5172
5173    def __init__(self, **args):
5174        unit = args.get("unit")
5175        if isinstance(unit, self.VAR_LIKE):
5176            args["unit"] = Var(
5177                this=(self.UNABBREVIATED_UNIT_NAME.get(unit.name) or unit.name).upper()
5178            )
5179        elif isinstance(unit, Week):
5180            unit.set("this", Var(this=unit.this.name.upper()))
5181
5182        super().__init__(**args)
5183
5184    @property
5185    def unit(self) -> t.Optional[Var | IntervalSpan]:
5186        return self.args.get("unit")

Automatically converts unit arg into a var.

TimeUnit(**args)
5173    def __init__(self, **args):
5174        unit = args.get("unit")
5175        if isinstance(unit, self.VAR_LIKE):
5176            args["unit"] = Var(
5177                this=(self.UNABBREVIATED_UNIT_NAME.get(unit.name) or unit.name).upper()
5178            )
5179        elif isinstance(unit, Week):
5180            unit.set("this", Var(this=unit.this.name.upper()))
5181
5182        super().__init__(**args)
arg_types = {'unit': False}
UNABBREVIATED_UNIT_NAME = {'D': 'DAY', 'H': 'HOUR', 'M': 'MINUTE', 'MS': 'MILLISECOND', 'NS': 'NANOSECOND', 'Q': 'QUARTER', 'S': 'SECOND', 'US': 'MICROSECOND', 'W': 'WEEK', 'Y': 'YEAR'}
VAR_LIKE = (<class 'Column'>, <class 'Literal'>, <class 'Var'>)
unit: Union[Var, IntervalSpan, NoneType]
5184    @property
5185    def unit(self) -> t.Optional[Var | IntervalSpan]:
5186        return self.args.get("unit")
key = 'timeunit'
class IntervalOp(TimeUnit):
5189class IntervalOp(TimeUnit):
5190    arg_types = {"unit": False, "expression": True}
5191
5192    def interval(self):
5193        return Interval(
5194            this=self.expression.copy(),
5195            unit=self.unit.copy() if self.unit else None,
5196        )
arg_types = {'unit': False, 'expression': True}
def interval(self):
5192    def interval(self):
5193        return Interval(
5194            this=self.expression.copy(),
5195            unit=self.unit.copy() if self.unit else None,
5196        )
key = 'intervalop'
class IntervalSpan(DataType):
5202class IntervalSpan(DataType):
5203    arg_types = {"this": True, "expression": True}
arg_types = {'this': True, 'expression': True}
key = 'intervalspan'
class Interval(TimeUnit):
5206class Interval(TimeUnit):
5207    arg_types = {"this": False, "unit": False}
arg_types = {'this': False, 'unit': False}
key = 'interval'
class IgnoreNulls(Expression):
5210class IgnoreNulls(Expression):
5211    pass
key = 'ignorenulls'
class RespectNulls(Expression):
5214class RespectNulls(Expression):
5215    pass
key = 'respectnulls'
class HavingMax(Expression):
5219class HavingMax(Expression):
5220    arg_types = {"this": True, "expression": True, "max": True}
arg_types = {'this': True, 'expression': True, 'max': True}
key = 'havingmax'
class Func(Condition):
5224class Func(Condition):
5225    """
5226    The base class for all function expressions.
5227
5228    Attributes:
5229        is_var_len_args (bool): if set to True the last argument defined in arg_types will be
5230            treated as a variable length argument and the argument's value will be stored as a list.
5231        _sql_names (list): the SQL name (1st item in the list) and aliases (subsequent items) for this
5232            function expression. These values are used to map this node to a name during parsing as
5233            well as to provide the function's name during SQL string generation. By default the SQL
5234            name is set to the expression's class name transformed to snake case.
5235    """
5236
5237    is_var_len_args = False
5238
5239    @classmethod
5240    def from_arg_list(cls, args):
5241        if cls.is_var_len_args:
5242            all_arg_keys = list(cls.arg_types)
5243            # If this function supports variable length argument treat the last argument as such.
5244            non_var_len_arg_keys = all_arg_keys[:-1] if cls.is_var_len_args else all_arg_keys
5245            num_non_var = len(non_var_len_arg_keys)
5246
5247            args_dict = {arg_key: arg for arg, arg_key in zip(args, non_var_len_arg_keys)}
5248            args_dict[all_arg_keys[-1]] = args[num_non_var:]
5249        else:
5250            args_dict = {arg_key: arg for arg, arg_key in zip(args, cls.arg_types)}
5251
5252        return cls(**args_dict)
5253
5254    @classmethod
5255    def sql_names(cls):
5256        if cls is Func:
5257            raise NotImplementedError(
5258                "SQL name is only supported by concrete function implementations"
5259            )
5260        if "_sql_names" not in cls.__dict__:
5261            cls._sql_names = [camel_to_snake_case(cls.__name__)]
5262        return cls._sql_names
5263
5264    @classmethod
5265    def sql_name(cls):
5266        return cls.sql_names()[0]
5267
5268    @classmethod
5269    def default_parser_mappings(cls):
5270        return {name: cls.from_arg_list for name in cls.sql_names()}

The base class for all function expressions.

Attributes:
  • is_var_len_args (bool): if set to True the last argument defined in arg_types will be treated as a variable length argument and the argument's value will be stored as a list.
  • _sql_names (list): the SQL name (1st item in the list) and aliases (subsequent items) for this function expression. These values are used to map this node to a name during parsing as well as to provide the function's name during SQL string generation. By default the SQL name is set to the expression's class name transformed to snake case.
is_var_len_args = False
@classmethod
def from_arg_list(cls, args):
5239    @classmethod
5240    def from_arg_list(cls, args):
5241        if cls.is_var_len_args:
5242            all_arg_keys = list(cls.arg_types)
5243            # If this function supports variable length argument treat the last argument as such.
5244            non_var_len_arg_keys = all_arg_keys[:-1] if cls.is_var_len_args else all_arg_keys
5245            num_non_var = len(non_var_len_arg_keys)
5246
5247            args_dict = {arg_key: arg for arg, arg_key in zip(args, non_var_len_arg_keys)}
5248            args_dict[all_arg_keys[-1]] = args[num_non_var:]
5249        else:
5250            args_dict = {arg_key: arg for arg, arg_key in zip(args, cls.arg_types)}
5251
5252        return cls(**args_dict)
@classmethod
def sql_names(cls):
5254    @classmethod
5255    def sql_names(cls):
5256        if cls is Func:
5257            raise NotImplementedError(
5258                "SQL name is only supported by concrete function implementations"
5259            )
5260        if "_sql_names" not in cls.__dict__:
5261            cls._sql_names = [camel_to_snake_case(cls.__name__)]
5262        return cls._sql_names
@classmethod
def sql_name(cls):
5264    @classmethod
5265    def sql_name(cls):
5266        return cls.sql_names()[0]
@classmethod
def default_parser_mappings(cls):
5268    @classmethod
5269    def default_parser_mappings(cls):
5270        return {name: cls.from_arg_list for name in cls.sql_names()}
key = 'func'
class AggFunc(Func):
5273class AggFunc(Func):
5274    pass
key = 'aggfunc'
class ParameterizedAgg(AggFunc):
5277class ParameterizedAgg(AggFunc):
5278    arg_types = {"this": True, "expressions": True, "params": True}
arg_types = {'this': True, 'expressions': True, 'params': True}
key = 'parameterizedagg'
class Abs(Func):
5281class Abs(Func):
5282    pass
key = 'abs'
class ArgMax(AggFunc):
5285class ArgMax(AggFunc):
5286    arg_types = {"this": True, "expression": True, "count": False}
5287    _sql_names = ["ARG_MAX", "ARGMAX", "MAX_BY"]
arg_types = {'this': True, 'expression': True, 'count': False}
key = 'argmax'
class ArgMin(AggFunc):
5290class ArgMin(AggFunc):
5291    arg_types = {"this": True, "expression": True, "count": False}
5292    _sql_names = ["ARG_MIN", "ARGMIN", "MIN_BY"]
arg_types = {'this': True, 'expression': True, 'count': False}
key = 'argmin'
class ApproxTopK(AggFunc):
5295class ApproxTopK(AggFunc):
5296    arg_types = {"this": True, "expression": False, "counters": False}
arg_types = {'this': True, 'expression': False, 'counters': False}
key = 'approxtopk'
class Flatten(Func):
5299class Flatten(Func):
5300    pass
key = 'flatten'
class Transform(Func):
5304class Transform(Func):
5305    arg_types = {"this": True, "expression": True}
arg_types = {'this': True, 'expression': True}
key = 'transform'
class Anonymous(Func):
5308class Anonymous(Func):
5309    arg_types = {"this": True, "expressions": False}
5310    is_var_len_args = True
5311
5312    @property
5313    def name(self) -> str:
5314        return self.this if isinstance(self.this, str) else self.this.name
arg_types = {'this': True, 'expressions': False}
is_var_len_args = True
name: str
5312    @property
5313    def name(self) -> str:
5314        return self.this if isinstance(self.this, str) else self.this.name
key = 'anonymous'
class AnonymousAggFunc(AggFunc):
5317class AnonymousAggFunc(AggFunc):
5318    arg_types = {"this": True, "expressions": False}
5319    is_var_len_args = True
arg_types = {'this': True, 'expressions': False}
is_var_len_args = True
key = 'anonymousaggfunc'
class CombinedAggFunc(AnonymousAggFunc):
5323class CombinedAggFunc(AnonymousAggFunc):
5324    arg_types = {"this": True, "expressions": False}
arg_types = {'this': True, 'expressions': False}
key = 'combinedaggfunc'
class CombinedParameterizedAgg(ParameterizedAgg):
5327class CombinedParameterizedAgg(ParameterizedAgg):
5328    arg_types = {"this": True, "expressions": True, "params": True}
arg_types = {'this': True, 'expressions': True, 'params': True}
key = 'combinedparameterizedagg'
class Hll(AggFunc):
5333class Hll(AggFunc):
5334    arg_types = {"this": True, "expressions": False}
5335    is_var_len_args = True
arg_types = {'this': True, 'expressions': False}
is_var_len_args = True
key = 'hll'
class ApproxDistinct(AggFunc):
5338class ApproxDistinct(AggFunc):
5339    arg_types = {"this": True, "accuracy": False}
5340    _sql_names = ["APPROX_DISTINCT", "APPROX_COUNT_DISTINCT"]
arg_types = {'this': True, 'accuracy': False}
key = 'approxdistinct'
class Apply(Func):
5343class Apply(Func):
5344    arg_types = {"this": True, "expression": True}
arg_types = {'this': True, 'expression': True}
key = 'apply'
class Array(Func):
5347class Array(Func):
5348    arg_types = {"expressions": False, "bracket_notation": False}
5349    is_var_len_args = True
arg_types = {'expressions': False, 'bracket_notation': False}
is_var_len_args = True
key = 'array'
class ToArray(Func):
5353class ToArray(Func):
5354    pass
key = 'toarray'
class List(Func):
5358class List(Func):
5359    arg_types = {"expressions": False}
5360    is_var_len_args = True
arg_types = {'expressions': False}
is_var_len_args = True
key = 'list'
class Pad(Func):
5364class Pad(Func):
5365    arg_types = {"this": True, "expression": True, "fill_pattern": False, "is_left": True}
arg_types = {'this': True, 'expression': True, 'fill_pattern': False, 'is_left': True}
key = 'pad'
class ToChar(Func):
5370class ToChar(Func):
5371    arg_types = {"this": True, "format": False, "nlsparam": False}
arg_types = {'this': True, 'format': False, 'nlsparam': False}
key = 'tochar'
class ToNumber(Func):
5376class ToNumber(Func):
5377    arg_types = {
5378        "this": True,
5379        "format": False,
5380        "nlsparam": False,
5381        "precision": False,
5382        "scale": False,
5383    }
arg_types = {'this': True, 'format': False, 'nlsparam': False, 'precision': False, 'scale': False}
key = 'tonumber'
class ToDouble(Func):
5387class ToDouble(Func):
5388    arg_types = {
5389        "this": True,
5390        "format": False,
5391    }
arg_types = {'this': True, 'format': False}
key = 'todouble'
class Columns(Func):
5394class Columns(Func):
5395    arg_types = {"this": True, "unpack": False}
arg_types = {'this': True, 'unpack': False}
key = 'columns'
class Convert(Func):
5399class Convert(Func):
5400    arg_types = {"this": True, "expression": True, "style": False}
arg_types = {'this': True, 'expression': True, 'style': False}
key = 'convert'
class ConvertTimezone(Func):
5403class ConvertTimezone(Func):
5404    arg_types = {"source_tz": False, "target_tz": True, "timestamp": True}
arg_types = {'source_tz': False, 'target_tz': True, 'timestamp': True}
key = 'converttimezone'
class GenerateSeries(Func):
5407class GenerateSeries(Func):
5408    arg_types = {"start": True, "end": True, "step": False, "is_end_exclusive": False}
arg_types = {'start': True, 'end': True, 'step': False, 'is_end_exclusive': False}
key = 'generateseries'
class ExplodingGenerateSeries(GenerateSeries):
5414class ExplodingGenerateSeries(GenerateSeries):
5415    pass
key = 'explodinggenerateseries'
class ArrayAgg(AggFunc):
5418class ArrayAgg(AggFunc):
5419    arg_types = {"this": True, "nulls_excluded": False}
arg_types = {'this': True, 'nulls_excluded': False}
key = 'arrayagg'
class ArrayUniqueAgg(AggFunc):
5422class ArrayUniqueAgg(AggFunc):
5423    pass
key = 'arrayuniqueagg'
class ArrayAll(Func):
5426class ArrayAll(Func):
5427    arg_types = {"this": True, "expression": True}
arg_types = {'this': True, 'expression': True}
key = 'arrayall'
class ArrayAny(Func):
5431class ArrayAny(Func):
5432    arg_types = {"this": True, "expression": True}
arg_types = {'this': True, 'expression': True}
key = 'arrayany'
class ArrayConcat(Func):
5435class ArrayConcat(Func):
5436    _sql_names = ["ARRAY_CONCAT", "ARRAY_CAT"]
5437    arg_types = {"this": True, "expressions": False}
5438    is_var_len_args = True
arg_types = {'this': True, 'expressions': False}
is_var_len_args = True
key = 'arrayconcat'
class ArrayConstructCompact(Func):
5441class ArrayConstructCompact(Func):
5442    arg_types = {"expressions": True}
5443    is_var_len_args = True
arg_types = {'expressions': True}
is_var_len_args = True
key = 'arrayconstructcompact'
class ArrayContains(Binary, Func):
5446class ArrayContains(Binary, Func):
5447    _sql_names = ["ARRAY_CONTAINS", "ARRAY_HAS"]
key = 'arraycontains'
class ArrayContainsAll(Binary, Func):
5450class ArrayContainsAll(Binary, Func):
5451    _sql_names = ["ARRAY_CONTAINS_ALL", "ARRAY_HAS_ALL"]
key = 'arraycontainsall'
class ArrayFilter(Func):
5454class ArrayFilter(Func):
5455    arg_types = {"this": True, "expression": True}
5456    _sql_names = ["FILTER", "ARRAY_FILTER"]
arg_types = {'this': True, 'expression': True}
key = 'arrayfilter'
class ArrayToString(Func):
5459class ArrayToString(Func):
5460    arg_types = {"this": True, "expression": True, "null": False}
5461    _sql_names = ["ARRAY_TO_STRING", "ARRAY_JOIN"]
arg_types = {'this': True, 'expression': True, 'null': False}
key = 'arraytostring'
class String(Func):
5465class String(Func):
5466    arg_types = {"this": True, "zone": False}
arg_types = {'this': True, 'zone': False}
key = 'string'
class StringToArray(Func):
5469class StringToArray(Func):
5470    arg_types = {"this": True, "expression": True, "null": False}
5471    _sql_names = ["STRING_TO_ARRAY", "SPLIT_BY_STRING"]
arg_types = {'this': True, 'expression': True, 'null': False}
key = 'stringtoarray'
class ArrayOverlaps(Binary, Func):
5474class ArrayOverlaps(Binary, Func):
5475    pass
key = 'arrayoverlaps'
class ArraySize(Func):
5478class ArraySize(Func):
5479    arg_types = {"this": True, "expression": False}
5480    _sql_names = ["ARRAY_SIZE", "ARRAY_LENGTH"]
arg_types = {'this': True, 'expression': False}
key = 'arraysize'
class ArraySort(Func):
5483class ArraySort(Func):
5484    arg_types = {"this": True, "expression": False}
arg_types = {'this': True, 'expression': False}
key = 'arraysort'
class ArraySum(Func):
5487class ArraySum(Func):
5488    arg_types = {"this": True, "expression": False}
arg_types = {'this': True, 'expression': False}
key = 'arraysum'
class ArrayUnionAgg(AggFunc):
5491class ArrayUnionAgg(AggFunc):
5492    pass
key = 'arrayunionagg'
class Avg(AggFunc):
5495class Avg(AggFunc):
5496    pass
key = 'avg'
class AnyValue(AggFunc):
5499class AnyValue(AggFunc):
5500    pass
key = 'anyvalue'
class Lag(AggFunc):
5503class Lag(AggFunc):
5504    arg_types = {"this": True, "offset": False, "default": False}
arg_types = {'this': True, 'offset': False, 'default': False}
key = 'lag'
class Lead(AggFunc):
5507class Lead(AggFunc):
5508    arg_types = {"this": True, "offset": False, "default": False}
arg_types = {'this': True, 'offset': False, 'default': False}
key = 'lead'
class First(AggFunc):
5513class First(AggFunc):
5514    pass
key = 'first'
class Last(AggFunc):
5517class Last(AggFunc):
5518    pass
key = 'last'
class FirstValue(AggFunc):
5521class FirstValue(AggFunc):
5522    pass
key = 'firstvalue'
class LastValue(AggFunc):
5525class LastValue(AggFunc):
5526    pass
key = 'lastvalue'
class NthValue(AggFunc):
5529class NthValue(AggFunc):
5530    arg_types = {"this": True, "offset": True}
arg_types = {'this': True, 'offset': True}
key = 'nthvalue'
class Case(Func):
5533class Case(Func):
5534    arg_types = {"this": False, "ifs": True, "default": False}
5535
5536    def when(self, condition: ExpOrStr, then: ExpOrStr, copy: bool = True, **opts) -> Case:
5537        instance = maybe_copy(self, copy)
5538        instance.append(
5539            "ifs",
5540            If(
5541                this=maybe_parse(condition, copy=copy, **opts),
5542                true=maybe_parse(then, copy=copy, **opts),
5543            ),
5544        )
5545        return instance
5546
5547    def else_(self, condition: ExpOrStr, copy: bool = True, **opts) -> Case:
5548        instance = maybe_copy(self, copy)
5549        instance.set("default", maybe_parse(condition, copy=copy, **opts))
5550        return instance
arg_types = {'this': False, 'ifs': True, 'default': False}
def when( self, condition: Union[str, Expression], then: Union[str, Expression], copy: bool = True, **opts) -> Case:
5536    def when(self, condition: ExpOrStr, then: ExpOrStr, copy: bool = True, **opts) -> Case:
5537        instance = maybe_copy(self, copy)
5538        instance.append(
5539            "ifs",
5540            If(
5541                this=maybe_parse(condition, copy=copy, **opts),
5542                true=maybe_parse(then, copy=copy, **opts),
5543            ),
5544        )
5545        return instance
def else_( self, condition: Union[str, Expression], copy: bool = True, **opts) -> Case:
5547    def else_(self, condition: ExpOrStr, copy: bool = True, **opts) -> Case:
5548        instance = maybe_copy(self, copy)
5549        instance.set("default", maybe_parse(condition, copy=copy, **opts))
5550        return instance
key = 'case'
class Cast(Func):
5553class Cast(Func):
5554    arg_types = {
5555        "this": True,
5556        "to": True,
5557        "format": False,
5558        "safe": False,
5559        "action": False,
5560        "default": False,
5561    }
5562
5563    @property
5564    def name(self) -> str:
5565        return self.this.name
5566
5567    @property
5568    def to(self) -> DataType:
5569        return self.args["to"]
5570
5571    @property
5572    def output_name(self) -> str:
5573        return self.name
5574
5575    def is_type(self, *dtypes: DATA_TYPE) -> bool:
5576        """
5577        Checks whether this Cast's DataType matches one of the provided data types. Nested types
5578        like arrays or structs will be compared using "structural equivalence" semantics, so e.g.
5579        array<int> != array<float>.
5580
5581        Args:
5582            dtypes: the data types to compare this Cast's DataType to.
5583
5584        Returns:
5585            True, if and only if there is a type in `dtypes` which is equal to this Cast's DataType.
5586        """
5587        return self.to.is_type(*dtypes)
arg_types = {'this': True, 'to': True, 'format': False, 'safe': False, 'action': False, 'default': False}
name: str
5563    @property
5564    def name(self) -> str:
5565        return self.this.name
to: DataType
5567    @property
5568    def to(self) -> DataType:
5569        return self.args["to"]
output_name: str
5571    @property
5572    def output_name(self) -> str:
5573        return self.name

Name of the output column if this expression is a selection.

If the Expression has no output name, an empty string is returned.

Example:
>>> from sqlglot import parse_one
>>> parse_one("SELECT a")sqlglot.expressions[0].output_name
'a'
>>> parse_one("SELECT b AS c")sqlglot.expressions[0].output_name
'c'
>>> parse_one("SELECT 1 + 2")sqlglot.expressions[0].output_name
''
def is_type( self, *dtypes: Union[str, DataType, DataType.Type]) -> bool:
5575    def is_type(self, *dtypes: DATA_TYPE) -> bool:
5576        """
5577        Checks whether this Cast's DataType matches one of the provided data types. Nested types
5578        like arrays or structs will be compared using "structural equivalence" semantics, so e.g.
5579        array<int> != array<float>.
5580
5581        Args:
5582            dtypes: the data types to compare this Cast's DataType to.
5583
5584        Returns:
5585            True, if and only if there is a type in `dtypes` which is equal to this Cast's DataType.
5586        """
5587        return self.to.is_type(*dtypes)

Checks whether this Cast's DataType matches one of the provided data types. Nested types like arrays or structs will be compared using "structural equivalence" semantics, so e.g. array != array.

Arguments:
  • dtypes: the data types to compare this Cast's DataType to.
Returns:

True, if and only if there is a type in dtypes which is equal to this Cast's DataType.

key = 'cast'
class TryCast(Cast):
5590class TryCast(Cast):
5591    pass
key = 'trycast'
class JSONCast(Cast):
5595class JSONCast(Cast):
5596    pass
key = 'jsoncast'
class Try(Func):
5599class Try(Func):
5600    pass
key = 'try'
class CastToStrType(Func):
5603class CastToStrType(Func):
5604    arg_types = {"this": True, "to": True}
arg_types = {'this': True, 'to': True}
key = 'casttostrtype'
class Collate(Binary, Func):
5607class Collate(Binary, Func):
5608    pass
key = 'collate'
class Ceil(Func):
5611class Ceil(Func):
5612    arg_types = {"this": True, "decimals": False, "to": False}
5613    _sql_names = ["CEIL", "CEILING"]
arg_types = {'this': True, 'decimals': False, 'to': False}
key = 'ceil'
class Coalesce(Func):
5616class Coalesce(Func):
5617    arg_types = {"this": True, "expressions": False, "is_nvl": False}
5618    is_var_len_args = True
5619    _sql_names = ["COALESCE", "IFNULL", "NVL"]
arg_types = {'this': True, 'expressions': False, 'is_nvl': False}
is_var_len_args = True
key = 'coalesce'
class Chr(Func):
5622class Chr(Func):
5623    arg_types = {"expressions": True, "charset": False}
5624    is_var_len_args = True
5625    _sql_names = ["CHR", "CHAR"]
arg_types = {'expressions': True, 'charset': False}
is_var_len_args = True
key = 'chr'
class Concat(Func):
5628class Concat(Func):
5629    arg_types = {"expressions": True, "safe": False, "coalesce": False}
5630    is_var_len_args = True
arg_types = {'expressions': True, 'safe': False, 'coalesce': False}
is_var_len_args = True
key = 'concat'
class ConcatWs(Concat):
5633class ConcatWs(Concat):
5634    _sql_names = ["CONCAT_WS"]
key = 'concatws'
class Contains(Func):
5637class Contains(Func):
5638    arg_types = {"this": True, "expression": True}
arg_types = {'this': True, 'expression': True}
key = 'contains'
class ConnectByRoot(Func):
5642class ConnectByRoot(Func):
5643    pass
key = 'connectbyroot'
class Count(AggFunc):
5646class Count(AggFunc):
5647    arg_types = {"this": False, "expressions": False, "big_int": False}
5648    is_var_len_args = True
arg_types = {'this': False, 'expressions': False, 'big_int': False}
is_var_len_args = True
key = 'count'
class CountIf(AggFunc):
5651class CountIf(AggFunc):
5652    _sql_names = ["COUNT_IF", "COUNTIF"]
key = 'countif'
class Cbrt(Func):
5656class Cbrt(Func):
5657    pass
key = 'cbrt'
class CurrentDate(Func):
5660class CurrentDate(Func):
5661    arg_types = {"this": False}
arg_types = {'this': False}
key = 'currentdate'
class CurrentDatetime(Func):
5664class CurrentDatetime(Func):
5665    arg_types = {"this": False}
arg_types = {'this': False}
key = 'currentdatetime'
class CurrentTime(Func):
5668class CurrentTime(Func):
5669    arg_types = {"this": False}
arg_types = {'this': False}
key = 'currenttime'
class CurrentTimestamp(Func):
5672class CurrentTimestamp(Func):
5673    arg_types = {"this": False, "sysdate": False}
arg_types = {'this': False, 'sysdate': False}
key = 'currenttimestamp'
class CurrentSchema(Func):
5676class CurrentSchema(Func):
5677    arg_types = {"this": False}
arg_types = {'this': False}
key = 'currentschema'
class CurrentUser(Func):
5680class CurrentUser(Func):
5681    arg_types = {"this": False}
arg_types = {'this': False}
key = 'currentuser'
class DateAdd(Func, IntervalOp):
5684class DateAdd(Func, IntervalOp):
5685    arg_types = {"this": True, "expression": True, "unit": False}
arg_types = {'this': True, 'expression': True, 'unit': False}
key = 'dateadd'
class DateBin(Func, IntervalOp):
5688class DateBin(Func, IntervalOp):
5689    arg_types = {"this": True, "expression": True, "unit": False, "zone": False}
arg_types = {'this': True, 'expression': True, 'unit': False, 'zone': False}
key = 'datebin'
class DateSub(Func, IntervalOp):
5692class DateSub(Func, IntervalOp):
5693    arg_types = {"this": True, "expression": True, "unit": False}
arg_types = {'this': True, 'expression': True, 'unit': False}
key = 'datesub'
class DateDiff(Func, TimeUnit):
5696class DateDiff(Func, TimeUnit):
5697    _sql_names = ["DATEDIFF", "DATE_DIFF"]
5698    arg_types = {"this": True, "expression": True, "unit": False}
arg_types = {'this': True, 'expression': True, 'unit': False}
key = 'datediff'
class DateTrunc(Func):
5701class DateTrunc(Func):
5702    arg_types = {"unit": True, "this": True, "zone": False}
5703
5704    def __init__(self, **args):
5705        # Across most dialects it's safe to unabbreviate the unit (e.g. 'Q' -> 'QUARTER') except Oracle
5706        # https://docs.oracle.com/en/database/oracle/oracle-database/21/sqlrf/ROUND-and-TRUNC-Date-Functions.html
5707        unabbreviate = args.pop("unabbreviate", True)
5708
5709        unit = args.get("unit")
5710        if isinstance(unit, TimeUnit.VAR_LIKE):
5711            unit_name = unit.name.upper()
5712            if unabbreviate and unit_name in TimeUnit.UNABBREVIATED_UNIT_NAME:
5713                unit_name = TimeUnit.UNABBREVIATED_UNIT_NAME[unit_name]
5714
5715            args["unit"] = Literal.string(unit_name)
5716        elif isinstance(unit, Week):
5717            unit.set("this", Literal.string(unit.this.name.upper()))
5718
5719        super().__init__(**args)
5720
5721    @property
5722    def unit(self) -> Expression:
5723        return self.args["unit"]
DateTrunc(**args)
5704    def __init__(self, **args):
5705        # Across most dialects it's safe to unabbreviate the unit (e.g. 'Q' -> 'QUARTER') except Oracle
5706        # https://docs.oracle.com/en/database/oracle/oracle-database/21/sqlrf/ROUND-and-TRUNC-Date-Functions.html
5707        unabbreviate = args.pop("unabbreviate", True)
5708
5709        unit = args.get("unit")
5710        if isinstance(unit, TimeUnit.VAR_LIKE):
5711            unit_name = unit.name.upper()
5712            if unabbreviate and unit_name in TimeUnit.UNABBREVIATED_UNIT_NAME:
5713                unit_name = TimeUnit.UNABBREVIATED_UNIT_NAME[unit_name]
5714
5715            args["unit"] = Literal.string(unit_name)
5716        elif isinstance(unit, Week):
5717            unit.set("this", Literal.string(unit.this.name.upper()))
5718
5719        super().__init__(**args)
arg_types = {'unit': True, 'this': True, 'zone': False}
unit: Expression
5721    @property
5722    def unit(self) -> Expression:
5723        return self.args["unit"]
key = 'datetrunc'
class Datetime(Func):
5728class Datetime(Func):
5729    arg_types = {"this": True, "expression": False}
arg_types = {'this': True, 'expression': False}
key = 'datetime'
class DatetimeAdd(Func, IntervalOp):
5732class DatetimeAdd(Func, IntervalOp):
5733    arg_types = {"this": True, "expression": True, "unit": False}
arg_types = {'this': True, 'expression': True, 'unit': False}
key = 'datetimeadd'
class DatetimeSub(Func, IntervalOp):
5736class DatetimeSub(Func, IntervalOp):
5737    arg_types = {"this": True, "expression": True, "unit": False}
arg_types = {'this': True, 'expression': True, 'unit': False}
key = 'datetimesub'
class DatetimeDiff(Func, TimeUnit):
5740class DatetimeDiff(Func, TimeUnit):
5741    arg_types = {"this": True, "expression": True, "unit": False}
arg_types = {'this': True, 'expression': True, 'unit': False}
key = 'datetimediff'
class DatetimeTrunc(Func, TimeUnit):
5744class DatetimeTrunc(Func, TimeUnit):
5745    arg_types = {"this": True, "unit": True, "zone": False}
arg_types = {'this': True, 'unit': True, 'zone': False}
key = 'datetimetrunc'
class DayOfWeek(Func):
5748class DayOfWeek(Func):
5749    _sql_names = ["DAY_OF_WEEK", "DAYOFWEEK"]
key = 'dayofweek'
class DayOfWeekIso(Func):
5754class DayOfWeekIso(Func):
5755    _sql_names = ["DAYOFWEEK_ISO", "ISODOW"]
key = 'dayofweekiso'
class DayOfMonth(Func):
5758class DayOfMonth(Func):
5759    _sql_names = ["DAY_OF_MONTH", "DAYOFMONTH"]
key = 'dayofmonth'
class DayOfYear(Func):
5762class DayOfYear(Func):
5763    _sql_names = ["DAY_OF_YEAR", "DAYOFYEAR"]
key = 'dayofyear'
class ToDays(Func):
5766class ToDays(Func):
5767    pass
key = 'todays'
class WeekOfYear(Func):
5770class WeekOfYear(Func):
5771    _sql_names = ["WEEK_OF_YEAR", "WEEKOFYEAR"]
key = 'weekofyear'
class MonthsBetween(Func):
5774class MonthsBetween(Func):
5775    arg_types = {"this": True, "expression": True, "roundoff": False}
arg_types = {'this': True, 'expression': True, 'roundoff': False}
key = 'monthsbetween'
class MakeInterval(Func):
5778class MakeInterval(Func):
5779    arg_types = {
5780        "year": False,
5781        "month": False,
5782        "day": False,
5783        "hour": False,
5784        "minute": False,
5785        "second": False,
5786    }
arg_types = {'year': False, 'month': False, 'day': False, 'hour': False, 'minute': False, 'second': False}
key = 'makeinterval'
class LastDay(Func, TimeUnit):
5789class LastDay(Func, TimeUnit):
5790    _sql_names = ["LAST_DAY", "LAST_DAY_OF_MONTH"]
5791    arg_types = {"this": True, "unit": False}
arg_types = {'this': True, 'unit': False}
key = 'lastday'
class Extract(Func):
5794class Extract(Func):
5795    arg_types = {"this": True, "expression": True}
arg_types = {'this': True, 'expression': True}
key = 'extract'
class Exists(Func, SubqueryPredicate):
5798class Exists(Func, SubqueryPredicate):
5799    arg_types = {"this": True, "expression": False}
arg_types = {'this': True, 'expression': False}
key = 'exists'
class Timestamp(Func):
5802class Timestamp(Func):
5803    arg_types = {"this": False, "zone": False, "with_tz": False}
arg_types = {'this': False, 'zone': False, 'with_tz': False}
key = 'timestamp'
class TimestampAdd(Func, TimeUnit):
5806class TimestampAdd(Func, TimeUnit):
5807    arg_types = {"this": True, "expression": True, "unit": False}
arg_types = {'this': True, 'expression': True, 'unit': False}
key = 'timestampadd'
class TimestampSub(Func, TimeUnit):
5810class TimestampSub(Func, TimeUnit):
5811    arg_types = {"this": True, "expression": True, "unit": False}
arg_types = {'this': True, 'expression': True, 'unit': False}
key = 'timestampsub'
class TimestampDiff(Func, TimeUnit):
5814class TimestampDiff(Func, TimeUnit):
5815    _sql_names = ["TIMESTAMPDIFF", "TIMESTAMP_DIFF"]
5816    arg_types = {"this": True, "expression": True, "unit": False}
arg_types = {'this': True, 'expression': True, 'unit': False}
key = 'timestampdiff'
class TimestampTrunc(Func, TimeUnit):
5819class TimestampTrunc(Func, TimeUnit):
5820    arg_types = {"this": True, "unit": True, "zone": False}
arg_types = {'this': True, 'unit': True, 'zone': False}
key = 'timestamptrunc'
class TimeAdd(Func, TimeUnit):
5823class TimeAdd(Func, TimeUnit):
5824    arg_types = {"this": True, "expression": True, "unit": False}
arg_types = {'this': True, 'expression': True, 'unit': False}
key = 'timeadd'
class TimeSub(Func, TimeUnit):
5827class TimeSub(Func, TimeUnit):
5828    arg_types = {"this": True, "expression": True, "unit": False}
arg_types = {'this': True, 'expression': True, 'unit': False}
key = 'timesub'
class TimeDiff(Func, TimeUnit):
5831class TimeDiff(Func, TimeUnit):
5832    arg_types = {"this": True, "expression": True, "unit": False}
arg_types = {'this': True, 'expression': True, 'unit': False}
key = 'timediff'
class TimeTrunc(Func, TimeUnit):
5835class TimeTrunc(Func, TimeUnit):
5836    arg_types = {"this": True, "unit": True, "zone": False}
arg_types = {'this': True, 'unit': True, 'zone': False}
key = 'timetrunc'
class DateFromParts(Func):
5839class DateFromParts(Func):
5840    _sql_names = ["DATE_FROM_PARTS", "DATEFROMPARTS"]
5841    arg_types = {"year": True, "month": True, "day": True}
arg_types = {'year': True, 'month': True, 'day': True}
key = 'datefromparts'
class TimeFromParts(Func):
5844class TimeFromParts(Func):
5845    _sql_names = ["TIME_FROM_PARTS", "TIMEFROMPARTS"]
5846    arg_types = {
5847        "hour": True,
5848        "min": True,
5849        "sec": True,
5850        "nano": False,
5851        "fractions": False,
5852        "precision": False,
5853    }
arg_types = {'hour': True, 'min': True, 'sec': True, 'nano': False, 'fractions': False, 'precision': False}
key = 'timefromparts'
class DateStrToDate(Func):
5856class DateStrToDate(Func):
5857    pass
key = 'datestrtodate'
class DateToDateStr(Func):
5860class DateToDateStr(Func):
5861    pass
key = 'datetodatestr'
class DateToDi(Func):
5864class DateToDi(Func):
5865    pass
key = 'datetodi'
class Date(Func):
5869class Date(Func):
5870    arg_types = {"this": False, "zone": False, "expressions": False}
5871    is_var_len_args = True
arg_types = {'this': False, 'zone': False, 'expressions': False}
is_var_len_args = True
key = 'date'
class Day(Func):
5874class Day(Func):
5875    pass
key = 'day'
class Decode(Func):
5878class Decode(Func):
5879    arg_types = {"this": True, "charset": True, "replace": False}
arg_types = {'this': True, 'charset': True, 'replace': False}
key = 'decode'
class DiToDate(Func):
5882class DiToDate(Func):
5883    pass
key = 'ditodate'
class Encode(Func):
5886class Encode(Func):
5887    arg_types = {"this": True, "charset": True}
arg_types = {'this': True, 'charset': True}
key = 'encode'
class Exp(Func):
5890class Exp(Func):
5891    pass
key = 'exp'
class Explode(Func, UDTF):
5895class Explode(Func, UDTF):
5896    arg_types = {"this": True, "expressions": False}
5897    is_var_len_args = True
arg_types = {'this': True, 'expressions': False}
is_var_len_args = True
key = 'explode'
class Inline(Func):
5901class Inline(Func):
5902    pass
key = 'inline'
class ExplodeOuter(Explode):
5905class ExplodeOuter(Explode):
5906    pass
key = 'explodeouter'
class Posexplode(Explode):
5909class Posexplode(Explode):
5910    pass
key = 'posexplode'
class PosexplodeOuter(Posexplode, ExplodeOuter):
5913class PosexplodeOuter(Posexplode, ExplodeOuter):
5914    pass
key = 'posexplodeouter'
class Unnest(Func, UDTF):
5917class Unnest(Func, UDTF):
5918    arg_types = {
5919        "expressions": True,
5920        "alias": False,
5921        "offset": False,
5922        "explode_array": False,
5923    }
5924
5925    @property
5926    def selects(self) -> t.List[Expression]:
5927        columns = super().selects
5928        offset = self.args.get("offset")
5929        if offset:
5930            columns = columns + [to_identifier("offset") if offset is True else offset]
5931        return columns
arg_types = {'expressions': True, 'alias': False, 'offset': False, 'explode_array': False}
selects: List[Expression]
5925    @property
5926    def selects(self) -> t.List[Expression]:
5927        columns = super().selects
5928        offset = self.args.get("offset")
5929        if offset:
5930            columns = columns + [to_identifier("offset") if offset is True else offset]
5931        return columns
key = 'unnest'
class Floor(Func):
5934class Floor(Func):
5935    arg_types = {"this": True, "decimals": False, "to": False}
arg_types = {'this': True, 'decimals': False, 'to': False}
key = 'floor'
class FromBase64(Func):
5938class FromBase64(Func):
5939    pass
key = 'frombase64'
class FeaturesAtTime(Func):
5942class FeaturesAtTime(Func):
5943    arg_types = {"this": True, "time": False, "num_rows": False, "ignore_feature_nulls": False}
arg_types = {'this': True, 'time': False, 'num_rows': False, 'ignore_feature_nulls': False}
key = 'featuresattime'
class ToBase64(Func):
5946class ToBase64(Func):
5947    pass
key = 'tobase64'
class FromISO8601Timestamp(Func):
5951class FromISO8601Timestamp(Func):
5952    _sql_names = ["FROM_ISO8601_TIMESTAMP"]
key = 'fromiso8601timestamp'
class GapFill(Func):
5955class GapFill(Func):
5956    arg_types = {
5957        "this": True,
5958        "ts_column": True,
5959        "bucket_width": True,
5960        "partitioning_columns": False,
5961        "value_columns": False,
5962        "origin": False,
5963        "ignore_nulls": False,
5964    }
arg_types = {'this': True, 'ts_column': True, 'bucket_width': True, 'partitioning_columns': False, 'value_columns': False, 'origin': False, 'ignore_nulls': False}
key = 'gapfill'
class GenerateDateArray(Func):
5968class GenerateDateArray(Func):
5969    arg_types = {"start": True, "end": True, "step": False}
arg_types = {'start': True, 'end': True, 'step': False}
key = 'generatedatearray'
class GenerateTimestampArray(Func):
5973class GenerateTimestampArray(Func):
5974    arg_types = {"start": True, "end": True, "step": True}
arg_types = {'start': True, 'end': True, 'step': True}
key = 'generatetimestamparray'
class Greatest(Func):
5977class Greatest(Func):
5978    arg_types = {"this": True, "expressions": False}
5979    is_var_len_args = True
arg_types = {'this': True, 'expressions': False}
is_var_len_args = True
key = 'greatest'
class OverflowTruncateBehavior(Expression):
5984class OverflowTruncateBehavior(Expression):
5985    arg_types = {"this": False, "with_count": True}
arg_types = {'this': False, 'with_count': True}
key = 'overflowtruncatebehavior'
class GroupConcat(AggFunc):
5988class GroupConcat(AggFunc):
5989    arg_types = {"this": True, "separator": False, "on_overflow": False}
arg_types = {'this': True, 'separator': False, 'on_overflow': False}
key = 'groupconcat'
class Hex(Func):
5992class Hex(Func):
5993    pass
key = 'hex'
class LowerHex(Hex):
5996class LowerHex(Hex):
5997    pass
key = 'lowerhex'
class And(Connector, Func):
6000class And(Connector, Func):
6001    pass
key = 'and'
class Or(Connector, Func):
6004class Or(Connector, Func):
6005    pass
key = 'or'
class Xor(Connector, Func):
6008class Xor(Connector, Func):
6009    arg_types = {"this": False, "expression": False, "expressions": False}
arg_types = {'this': False, 'expression': False, 'expressions': False}
key = 'xor'
class If(Func):
6012class If(Func):
6013    arg_types = {"this": True, "true": True, "false": False}
6014    _sql_names = ["IF", "IIF"]
arg_types = {'this': True, 'true': True, 'false': False}
key = 'if'
class Nullif(Func):
6017class Nullif(Func):
6018    arg_types = {"this": True, "expression": True}
arg_types = {'this': True, 'expression': True}
key = 'nullif'
class Initcap(Func):
6021class Initcap(Func):
6022    arg_types = {"this": True, "expression": False}
arg_types = {'this': True, 'expression': False}
key = 'initcap'
class IsAscii(Func):
6025class IsAscii(Func):
6026    pass
key = 'isascii'
class IsNan(Func):
6029class IsNan(Func):
6030    _sql_names = ["IS_NAN", "ISNAN"]
key = 'isnan'
class Int64(Func):
6034class Int64(Func):
6035    pass
key = 'int64'
class IsInf(Func):
6038class IsInf(Func):
6039    _sql_names = ["IS_INF", "ISINF"]
key = 'isinf'
class JSON(Expression):
6043class JSON(Expression):
6044    arg_types = {"this": False, "with": False, "unique": False}
arg_types = {'this': False, 'with': False, 'unique': False}
key = 'json'
class JSONPath(Expression):
6047class JSONPath(Expression):
6048    arg_types = {"expressions": True, "escape": False}
6049
6050    @property
6051    def output_name(self) -> str:
6052        last_segment = self.expressions[-1].this
6053        return last_segment if isinstance(last_segment, str) else ""
arg_types = {'expressions': True, 'escape': False}
output_name: str
6050    @property
6051    def output_name(self) -> str:
6052        last_segment = self.expressions[-1].this
6053        return last_segment if isinstance(last_segment, str) else ""

Name of the output column if this expression is a selection.

If the Expression has no output name, an empty string is returned.

Example:
>>> from sqlglot import parse_one
>>> parse_one("SELECT a")sqlglot.expressions[0].output_name
'a'
>>> parse_one("SELECT b AS c")sqlglot.expressions[0].output_name
'c'
>>> parse_one("SELECT 1 + 2")sqlglot.expressions[0].output_name
''
key = 'jsonpath'
class JSONPathPart(Expression):
6056class JSONPathPart(Expression):
6057    arg_types = {}
arg_types = {}
key = 'jsonpathpart'
class JSONPathFilter(JSONPathPart):
6060class JSONPathFilter(JSONPathPart):
6061    arg_types = {"this": True}
arg_types = {'this': True}
key = 'jsonpathfilter'
class JSONPathKey(JSONPathPart):
6064class JSONPathKey(JSONPathPart):
6065    arg_types = {"this": True}
arg_types = {'this': True}
key = 'jsonpathkey'
class JSONPathRecursive(JSONPathPart):
6068class JSONPathRecursive(JSONPathPart):
6069    arg_types = {"this": False}
arg_types = {'this': False}
key = 'jsonpathrecursive'
class JSONPathRoot(JSONPathPart):
6072class JSONPathRoot(JSONPathPart):
6073    pass
key = 'jsonpathroot'
class JSONPathScript(JSONPathPart):
6076class JSONPathScript(JSONPathPart):
6077    arg_types = {"this": True}
arg_types = {'this': True}
key = 'jsonpathscript'
class JSONPathSlice(JSONPathPart):
6080class JSONPathSlice(JSONPathPart):
6081    arg_types = {"start": False, "end": False, "step": False}
arg_types = {'start': False, 'end': False, 'step': False}
key = 'jsonpathslice'
class JSONPathSelector(JSONPathPart):
6084class JSONPathSelector(JSONPathPart):
6085    arg_types = {"this": True}
arg_types = {'this': True}
key = 'jsonpathselector'
class JSONPathSubscript(JSONPathPart):
6088class JSONPathSubscript(JSONPathPart):
6089    arg_types = {"this": True}
arg_types = {'this': True}
key = 'jsonpathsubscript'
class JSONPathUnion(JSONPathPart):
6092class JSONPathUnion(JSONPathPart):
6093    arg_types = {"expressions": True}
arg_types = {'expressions': True}
key = 'jsonpathunion'
class JSONPathWildcard(JSONPathPart):
6096class JSONPathWildcard(JSONPathPart):
6097    pass
key = 'jsonpathwildcard'
class FormatJson(Expression):
6100class FormatJson(Expression):
6101    pass
key = 'formatjson'
class JSONKeyValue(Expression):
6104class JSONKeyValue(Expression):
6105    arg_types = {"this": True, "expression": True}
arg_types = {'this': True, 'expression': True}
key = 'jsonkeyvalue'
class JSONObject(Func):
6108class JSONObject(Func):
6109    arg_types = {
6110        "expressions": False,
6111        "null_handling": False,
6112        "unique_keys": False,
6113        "return_type": False,
6114        "encoding": False,
6115    }
arg_types = {'expressions': False, 'null_handling': False, 'unique_keys': False, 'return_type': False, 'encoding': False}
key = 'jsonobject'
class JSONObjectAgg(AggFunc):
6118class JSONObjectAgg(AggFunc):
6119    arg_types = {
6120        "expressions": False,
6121        "null_handling": False,
6122        "unique_keys": False,
6123        "return_type": False,
6124        "encoding": False,
6125    }
arg_types = {'expressions': False, 'null_handling': False, 'unique_keys': False, 'return_type': False, 'encoding': False}
key = 'jsonobjectagg'
class JSONBObjectAgg(AggFunc):
6129class JSONBObjectAgg(AggFunc):
6130    arg_types = {"this": True, "expression": True}
arg_types = {'this': True, 'expression': True}
key = 'jsonbobjectagg'
class JSONArray(Func):
6134class JSONArray(Func):
6135    arg_types = {
6136        "expressions": True,
6137        "null_handling": False,
6138        "return_type": False,
6139        "strict": False,
6140    }
arg_types = {'expressions': True, 'null_handling': False, 'return_type': False, 'strict': False}
key = 'jsonarray'
class JSONArrayAgg(Func):
6144class JSONArrayAgg(Func):
6145    arg_types = {
6146        "this": True,
6147        "order": False,
6148        "null_handling": False,
6149        "return_type": False,
6150        "strict": False,
6151    }
arg_types = {'this': True, 'order': False, 'null_handling': False, 'return_type': False, 'strict': False}
key = 'jsonarrayagg'
class JSONExists(Func):
6154class JSONExists(Func):
6155    arg_types = {"this": True, "path": True, "passing": False, "on_condition": False}
arg_types = {'this': True, 'path': True, 'passing': False, 'on_condition': False}
key = 'jsonexists'
class JSONColumnDef(Expression):
6160class JSONColumnDef(Expression):
6161    arg_types = {"this": False, "kind": False, "path": False, "nested_schema": False}
arg_types = {'this': False, 'kind': False, 'path': False, 'nested_schema': False}
key = 'jsoncolumndef'
class JSONSchema(Expression):
6164class JSONSchema(Expression):
6165    arg_types = {"expressions": True}
arg_types = {'expressions': True}
key = 'jsonschema'
class JSONValue(Expression):
6169class JSONValue(Expression):
6170    arg_types = {
6171        "this": True,
6172        "path": True,
6173        "returning": False,
6174        "on_condition": False,
6175    }
arg_types = {'this': True, 'path': True, 'returning': False, 'on_condition': False}
key = 'jsonvalue'
class JSONValueArray(Func):
6178class JSONValueArray(Func):
6179    arg_types = {"this": True, "expression": False}
arg_types = {'this': True, 'expression': False}
key = 'jsonvaluearray'
class JSONTable(Func):
6183class JSONTable(Func):
6184    arg_types = {
6185        "this": True,
6186        "schema": True,
6187        "path": False,
6188        "error_handling": False,
6189        "empty_handling": False,
6190    }
arg_types = {'this': True, 'schema': True, 'path': False, 'error_handling': False, 'empty_handling': False}
key = 'jsontable'
class ObjectInsert(Func):
6194class ObjectInsert(Func):
6195    arg_types = {
6196        "this": True,
6197        "key": True,
6198        "value": True,
6199        "update_flag": False,
6200    }
arg_types = {'this': True, 'key': True, 'value': True, 'update_flag': False}
key = 'objectinsert'
class OpenJSONColumnDef(Expression):
6203class OpenJSONColumnDef(Expression):
6204    arg_types = {"this": True, "kind": True, "path": False, "as_json": False}
arg_types = {'this': True, 'kind': True, 'path': False, 'as_json': False}
key = 'openjsoncolumndef'
class OpenJSON(Func):
6207class OpenJSON(Func):
6208    arg_types = {"this": True, "path": False, "expressions": False}
arg_types = {'this': True, 'path': False, 'expressions': False}
key = 'openjson'
class JSONBContains(Binary, Func):
6211class JSONBContains(Binary, Func):
6212    _sql_names = ["JSONB_CONTAINS"]
key = 'jsonbcontains'
class JSONBExists(Func):
6215class JSONBExists(Func):
6216    arg_types = {"this": True, "path": True}
6217    _sql_names = ["JSONB_EXISTS"]
arg_types = {'this': True, 'path': True}
key = 'jsonbexists'
class JSONExtract(Binary, Func):
6220class JSONExtract(Binary, Func):
6221    arg_types = {
6222        "this": True,
6223        "expression": True,
6224        "only_json_types": False,
6225        "expressions": False,
6226        "variant_extract": False,
6227        "json_query": False,
6228        "option": False,
6229        "quote": False,
6230        "on_condition": False,
6231    }
6232    _sql_names = ["JSON_EXTRACT"]
6233    is_var_len_args = True
6234
6235    @property
6236    def output_name(self) -> str:
6237        return self.expression.output_name if not self.expressions else ""
arg_types = {'this': True, 'expression': True, 'only_json_types': False, 'expressions': False, 'variant_extract': False, 'json_query': False, 'option': False, 'quote': False, 'on_condition': False}
is_var_len_args = True
output_name: str
6235    @property
6236    def output_name(self) -> str:
6237        return self.expression.output_name if not self.expressions else ""

Name of the output column if this expression is a selection.

If the Expression has no output name, an empty string is returned.

Example:
>>> from sqlglot import parse_one
>>> parse_one("SELECT a")sqlglot.expressions[0].output_name
'a'
>>> parse_one("SELECT b AS c")sqlglot.expressions[0].output_name
'c'
>>> parse_one("SELECT 1 + 2")sqlglot.expressions[0].output_name
''
key = 'jsonextract'
class JSONExtractQuote(Expression):
6241class JSONExtractQuote(Expression):
6242    arg_types = {
6243        "option": True,
6244        "scalar": False,
6245    }
arg_types = {'option': True, 'scalar': False}
key = 'jsonextractquote'
class JSONExtractArray(Func):
6248class JSONExtractArray(Func):
6249    arg_types = {"this": True, "expression": False}
6250    _sql_names = ["JSON_EXTRACT_ARRAY"]
arg_types = {'this': True, 'expression': False}
key = 'jsonextractarray'
class JSONExtractScalar(Binary, Func):
6253class JSONExtractScalar(Binary, Func):
6254    arg_types = {"this": True, "expression": True, "only_json_types": False, "expressions": False}
6255    _sql_names = ["JSON_EXTRACT_SCALAR"]
6256    is_var_len_args = True
6257
6258    @property
6259    def output_name(self) -> str:
6260        return self.expression.output_name
arg_types = {'this': True, 'expression': True, 'only_json_types': False, 'expressions': False}
is_var_len_args = True
output_name: str
6258    @property
6259    def output_name(self) -> str:
6260        return self.expression.output_name

Name of the output column if this expression is a selection.

If the Expression has no output name, an empty string is returned.

Example:
>>> from sqlglot import parse_one
>>> parse_one("SELECT a")sqlglot.expressions[0].output_name
'a'
>>> parse_one("SELECT b AS c")sqlglot.expressions[0].output_name
'c'
>>> parse_one("SELECT 1 + 2")sqlglot.expressions[0].output_name
''
key = 'jsonextractscalar'
class JSONBExtract(Binary, Func):
6263class JSONBExtract(Binary, Func):
6264    _sql_names = ["JSONB_EXTRACT"]
key = 'jsonbextract'
class JSONBExtractScalar(Binary, Func):
6267class JSONBExtractScalar(Binary, Func):
6268    _sql_names = ["JSONB_EXTRACT_SCALAR"]
key = 'jsonbextractscalar'
class JSONFormat(Func):
6271class JSONFormat(Func):
6272    arg_types = {"this": False, "options": False}
6273    _sql_names = ["JSON_FORMAT"]
arg_types = {'this': False, 'options': False}
key = 'jsonformat'
class JSONArrayContains(Binary, Predicate, Func):
6277class JSONArrayContains(Binary, Predicate, Func):
6278    _sql_names = ["JSON_ARRAY_CONTAINS"]
key = 'jsonarraycontains'
class ParseJSON(Func):
6281class ParseJSON(Func):
6282    # BigQuery, Snowflake have PARSE_JSON, Presto has JSON_PARSE
6283    # Snowflake also has TRY_PARSE_JSON, which is represented using `safe`
6284    _sql_names = ["PARSE_JSON", "JSON_PARSE"]
6285    arg_types = {"this": True, "expression": False, "safe": False}
arg_types = {'this': True, 'expression': False, 'safe': False}
key = 'parsejson'
class Least(Func):
6288class Least(Func):
6289    arg_types = {"this": True, "expressions": False}
6290    is_var_len_args = True
arg_types = {'this': True, 'expressions': False}
is_var_len_args = True
key = 'least'
class Left(Func):
6293class Left(Func):
6294    arg_types = {"this": True, "expression": True}
arg_types = {'this': True, 'expression': True}
key = 'left'
class Length(Func):
6301class Length(Func):
6302    arg_types = {"this": True, "binary": False, "encoding": False}
6303    _sql_names = ["LENGTH", "LEN", "CHAR_LENGTH", "CHARACTER_LENGTH"]
arg_types = {'this': True, 'binary': False, 'encoding': False}
key = 'length'
class Levenshtein(Func):
6306class Levenshtein(Func):
6307    arg_types = {
6308        "this": True,
6309        "expression": False,
6310        "ins_cost": False,
6311        "del_cost": False,
6312        "sub_cost": False,
6313        "max_dist": False,
6314    }
arg_types = {'this': True, 'expression': False, 'ins_cost': False, 'del_cost': False, 'sub_cost': False, 'max_dist': False}
key = 'levenshtein'
class Ln(Func):
6317class Ln(Func):
6318    pass
key = 'ln'
class Log(Func):
6321class Log(Func):
6322    arg_types = {"this": True, "expression": False}
arg_types = {'this': True, 'expression': False}
key = 'log'
class LogicalOr(AggFunc):
6325class LogicalOr(AggFunc):
6326    _sql_names = ["LOGICAL_OR", "BOOL_OR", "BOOLOR_AGG"]
key = 'logicalor'
class LogicalAnd(AggFunc):
6329class LogicalAnd(AggFunc):
6330    _sql_names = ["LOGICAL_AND", "BOOL_AND", "BOOLAND_AGG"]
key = 'logicaland'
class Lower(Func):
6333class Lower(Func):
6334    _sql_names = ["LOWER", "LCASE"]
key = 'lower'
class Map(Func):
6337class Map(Func):
6338    arg_types = {"keys": False, "values": False}
6339
6340    @property
6341    def keys(self) -> t.List[Expression]:
6342        keys = self.args.get("keys")
6343        return keys.expressions if keys else []
6344
6345    @property
6346    def values(self) -> t.List[Expression]:
6347        values = self.args.get("values")
6348        return values.expressions if values else []
arg_types = {'keys': False, 'values': False}
keys: List[Expression]
6340    @property
6341    def keys(self) -> t.List[Expression]:
6342        keys = self.args.get("keys")
6343        return keys.expressions if keys else []
values: List[Expression]
6345    @property
6346    def values(self) -> t.List[Expression]:
6347        values = self.args.get("values")
6348        return values.expressions if values else []
key = 'map'
class ToMap(Func):
6352class ToMap(Func):
6353    pass
key = 'tomap'
class MapFromEntries(Func):
6356class MapFromEntries(Func):
6357    pass
key = 'mapfromentries'
class ScopeResolution(Expression):
6361class ScopeResolution(Expression):
6362    arg_types = {"this": False, "expression": True}
arg_types = {'this': False, 'expression': True}
key = 'scoperesolution'
class Stream(Expression):
6365class Stream(Expression):
6366    pass
key = 'stream'
class StarMap(Func):
6369class StarMap(Func):
6370    pass
key = 'starmap'
class VarMap(Func):
6373class VarMap(Func):
6374    arg_types = {"keys": True, "values": True}
6375    is_var_len_args = True
6376
6377    @property
6378    def keys(self) -> t.List[Expression]:
6379        return self.args["keys"].expressions
6380
6381    @property
6382    def values(self) -> t.List[Expression]:
6383        return self.args["values"].expressions
arg_types = {'keys': True, 'values': True}
is_var_len_args = True
keys: List[Expression]
6377    @property
6378    def keys(self) -> t.List[Expression]:
6379        return self.args["keys"].expressions
values: List[Expression]
6381    @property
6382    def values(self) -> t.List[Expression]:
6383        return self.args["values"].expressions
key = 'varmap'
class MatchAgainst(Func):
6387class MatchAgainst(Func):
6388    arg_types = {"this": True, "expressions": True, "modifier": False}
arg_types = {'this': True, 'expressions': True, 'modifier': False}
key = 'matchagainst'
class Max(AggFunc):
6391class Max(AggFunc):
6392    arg_types = {"this": True, "expressions": False}
6393    is_var_len_args = True
arg_types = {'this': True, 'expressions': False}
is_var_len_args = True
key = 'max'
class MD5(Func):
6396class MD5(Func):
6397    _sql_names = ["MD5"]
key = 'md5'
class MD5Digest(Func):
6401class MD5Digest(Func):
6402    _sql_names = ["MD5_DIGEST"]
key = 'md5digest'
class Median(AggFunc):
6405class Median(AggFunc):
6406    pass
key = 'median'
class Min(AggFunc):
6409class Min(AggFunc):
6410    arg_types = {"this": True, "expressions": False}
6411    is_var_len_args = True
arg_types = {'this': True, 'expressions': False}
is_var_len_args = True
key = 'min'
class Month(Func):
6414class Month(Func):
6415    pass
key = 'month'
class AddMonths(Func):
6418class AddMonths(Func):
6419    arg_types = {"this": True, "expression": True}
arg_types = {'this': True, 'expression': True}
key = 'addmonths'
class Nvl2(Func):
6422class Nvl2(Func):
6423    arg_types = {"this": True, "true": True, "false": False}
arg_types = {'this': True, 'true': True, 'false': False}
key = 'nvl2'
class Normalize(Func):
6426class Normalize(Func):
6427    arg_types = {"this": True, "form": False}
arg_types = {'this': True, 'form': False}
key = 'normalize'
class Overlay(Func):
6430class Overlay(Func):
6431    arg_types = {"this": True, "expression": True, "from": True, "for": False}
arg_types = {'this': True, 'expression': True, 'from': True, 'for': False}
key = 'overlay'
class Predict(Func):
6435class Predict(Func):
6436    arg_types = {"this": True, "expression": True, "params_struct": False}
arg_types = {'this': True, 'expression': True, 'params_struct': False}
key = 'predict'
class Pow(Binary, Func):
6439class Pow(Binary, Func):
6440    _sql_names = ["POWER", "POW"]
key = 'pow'
class PercentileCont(AggFunc):
6443class PercentileCont(AggFunc):
6444    arg_types = {"this": True, "expression": False}
arg_types = {'this': True, 'expression': False}
key = 'percentilecont'
class PercentileDisc(AggFunc):
6447class PercentileDisc(AggFunc):
6448    arg_types = {"this": True, "expression": False}
arg_types = {'this': True, 'expression': False}
key = 'percentiledisc'
class Quantile(AggFunc):
6451class Quantile(AggFunc):
6452    arg_types = {"this": True, "quantile": True}
arg_types = {'this': True, 'quantile': True}
key = 'quantile'
class ApproxQuantile(Quantile):
6455class ApproxQuantile(Quantile):
6456    arg_types = {"this": True, "quantile": True, "accuracy": False, "weight": False}
arg_types = {'this': True, 'quantile': True, 'accuracy': False, 'weight': False}
key = 'approxquantile'
class Quarter(Func):
6459class Quarter(Func):
6460    pass
key = 'quarter'
class Rand(Func):
6465class Rand(Func):
6466    _sql_names = ["RAND", "RANDOM"]
6467    arg_types = {"this": False, "lower": False, "upper": False}
arg_types = {'this': False, 'lower': False, 'upper': False}
key = 'rand'
class Randn(Func):
6470class Randn(Func):
6471    arg_types = {"this": False}
arg_types = {'this': False}
key = 'randn'
class RangeN(Func):
6474class RangeN(Func):
6475    arg_types = {"this": True, "expressions": True, "each": False}
arg_types = {'this': True, 'expressions': True, 'each': False}
key = 'rangen'
class ReadCSV(Func):
6478class ReadCSV(Func):
6479    _sql_names = ["READ_CSV"]
6480    is_var_len_args = True
6481    arg_types = {"this": True, "expressions": False}
is_var_len_args = True
arg_types = {'this': True, 'expressions': False}
key = 'readcsv'
class Reduce(Func):
6484class Reduce(Func):
6485    arg_types = {"this": True, "initial": True, "merge": True, "finish": False}
arg_types = {'this': True, 'initial': True, 'merge': True, 'finish': False}
key = 'reduce'
class RegexpExtract(Func):
6488class RegexpExtract(Func):
6489    arg_types = {
6490        "this": True,
6491        "expression": True,
6492        "position": False,
6493        "occurrence": False,
6494        "parameters": False,
6495        "group": False,
6496    }
arg_types = {'this': True, 'expression': True, 'position': False, 'occurrence': False, 'parameters': False, 'group': False}
key = 'regexpextract'
class RegexpExtractAll(Func):
6499class RegexpExtractAll(Func):
6500    arg_types = {
6501        "this": True,
6502        "expression": True,
6503        "position": False,
6504        "occurrence": False,
6505        "parameters": False,
6506        "group": False,
6507    }
arg_types = {'this': True, 'expression': True, 'position': False, 'occurrence': False, 'parameters': False, 'group': False}
key = 'regexpextractall'
class RegexpReplace(Func):
6510class RegexpReplace(Func):
6511    arg_types = {
6512        "this": True,
6513        "expression": True,
6514        "replacement": False,
6515        "position": False,
6516        "occurrence": False,
6517        "modifiers": False,
6518    }
arg_types = {'this': True, 'expression': True, 'replacement': False, 'position': False, 'occurrence': False, 'modifiers': False}
key = 'regexpreplace'
class RegexpLike(Binary, Func):
6521class RegexpLike(Binary, Func):
6522    arg_types = {"this": True, "expression": True, "flag": False}
arg_types = {'this': True, 'expression': True, 'flag': False}
key = 'regexplike'
class RegexpILike(Binary, Func):
6525class RegexpILike(Binary, Func):
6526    arg_types = {"this": True, "expression": True, "flag": False}
arg_types = {'this': True, 'expression': True, 'flag': False}
key = 'regexpilike'
class RegexpSplit(Func):
6531class RegexpSplit(Func):
6532    arg_types = {"this": True, "expression": True, "limit": False}
arg_types = {'this': True, 'expression': True, 'limit': False}
key = 'regexpsplit'
class Repeat(Func):
6535class Repeat(Func):
6536    arg_types = {"this": True, "times": True}
arg_types = {'this': True, 'times': True}
key = 'repeat'
class Round(Func):
6541class Round(Func):
6542    arg_types = {"this": True, "decimals": False, "truncate": False}
arg_types = {'this': True, 'decimals': False, 'truncate': False}
key = 'round'
class RowNumber(Func):
6545class RowNumber(Func):
6546    arg_types = {"this": False}
arg_types = {'this': False}
key = 'rownumber'
class SafeDivide(Func):
6549class SafeDivide(Func):
6550    arg_types = {"this": True, "expression": True}
arg_types = {'this': True, 'expression': True}
key = 'safedivide'
class SHA(Func):
6553class SHA(Func):
6554    _sql_names = ["SHA", "SHA1"]
key = 'sha'
class SHA2(Func):
6557class SHA2(Func):
6558    _sql_names = ["SHA2"]
6559    arg_types = {"this": True, "length": False}
arg_types = {'this': True, 'length': False}
key = 'sha2'
class Sign(Func):
6562class Sign(Func):
6563    _sql_names = ["SIGN", "SIGNUM"]
key = 'sign'
class SortArray(Func):
6566class SortArray(Func):
6567    arg_types = {"this": True, "asc": False}
arg_types = {'this': True, 'asc': False}
key = 'sortarray'
class Split(Func):
6570class Split(Func):
6571    arg_types = {"this": True, "expression": True, "limit": False}
arg_types = {'this': True, 'expression': True, 'limit': False}
key = 'split'
class SplitPart(Func):
6575class SplitPart(Func):
6576    arg_types = {"this": True, "delimiter": True, "part_index": True}
arg_types = {'this': True, 'delimiter': True, 'part_index': True}
key = 'splitpart'
class Substring(Func):
6581class Substring(Func):
6582    _sql_names = ["SUBSTRING", "SUBSTR"]
6583    arg_types = {"this": True, "start": False, "length": False}
arg_types = {'this': True, 'start': False, 'length': False}
key = 'substring'
class StandardHash(Func):
6586class StandardHash(Func):
6587    arg_types = {"this": True, "expression": False}
arg_types = {'this': True, 'expression': False}
key = 'standardhash'
class StartsWith(Func):
6590class StartsWith(Func):
6591    _sql_names = ["STARTS_WITH", "STARTSWITH"]
6592    arg_types = {"this": True, "expression": True}
arg_types = {'this': True, 'expression': True}
key = 'startswith'
class StrPosition(Func):
6595class StrPosition(Func):
6596    arg_types = {
6597        "this": True,
6598        "substr": True,
6599        "position": False,
6600        "occurrence": False,
6601    }
arg_types = {'this': True, 'substr': True, 'position': False, 'occurrence': False}
key = 'strposition'
class StrToDate(Func):
6604class StrToDate(Func):
6605    arg_types = {"this": True, "format": False, "safe": False}
arg_types = {'this': True, 'format': False, 'safe': False}
key = 'strtodate'
class StrToTime(Func):
6608class StrToTime(Func):
6609    arg_types = {"this": True, "format": True, "zone": False, "safe": False}
arg_types = {'this': True, 'format': True, 'zone': False, 'safe': False}
key = 'strtotime'
class StrToUnix(Func):
6614class StrToUnix(Func):
6615    arg_types = {"this": False, "format": False}
arg_types = {'this': False, 'format': False}
key = 'strtounix'
class StrToMap(Func):
6620class StrToMap(Func):
6621    arg_types = {
6622        "this": True,
6623        "pair_delim": False,
6624        "key_value_delim": False,
6625        "duplicate_resolution_callback": False,
6626    }
arg_types = {'this': True, 'pair_delim': False, 'key_value_delim': False, 'duplicate_resolution_callback': False}
key = 'strtomap'
class NumberToStr(Func):
6629class NumberToStr(Func):
6630    arg_types = {"this": True, "format": True, "culture": False}
arg_types = {'this': True, 'format': True, 'culture': False}
key = 'numbertostr'
class FromBase(Func):
6633class FromBase(Func):
6634    arg_types = {"this": True, "expression": True}
arg_types = {'this': True, 'expression': True}
key = 'frombase'
class Struct(Func):
6637class Struct(Func):
6638    arg_types = {"expressions": False}
6639    is_var_len_args = True
arg_types = {'expressions': False}
is_var_len_args = True
key = 'struct'
class StructExtract(Func):
6642class StructExtract(Func):
6643    arg_types = {"this": True, "expression": True}
arg_types = {'this': True, 'expression': True}
key = 'structextract'
class Stuff(Func):
6648class Stuff(Func):
6649    _sql_names = ["STUFF", "INSERT"]
6650    arg_types = {"this": True, "start": True, "length": True, "expression": True}
arg_types = {'this': True, 'start': True, 'length': True, 'expression': True}
key = 'stuff'
class Sum(AggFunc):
6653class Sum(AggFunc):
6654    pass
key = 'sum'
class Sqrt(Func):
6657class Sqrt(Func):
6658    pass
key = 'sqrt'
class Stddev(AggFunc):
6661class Stddev(AggFunc):
6662    _sql_names = ["STDDEV", "STDEV"]
key = 'stddev'
class StddevPop(AggFunc):
6665class StddevPop(AggFunc):
6666    pass
key = 'stddevpop'
class StddevSamp(AggFunc):
6669class StddevSamp(AggFunc):
6670    pass
key = 'stddevsamp'
class Time(Func):
6674class Time(Func):
6675    arg_types = {"this": False, "zone": False}
arg_types = {'this': False, 'zone': False}
key = 'time'
class TimeToStr(Func):
6678class TimeToStr(Func):
6679    arg_types = {"this": True, "format": True, "culture": False, "zone": False}
arg_types = {'this': True, 'format': True, 'culture': False, 'zone': False}
key = 'timetostr'
class TimeToTimeStr(Func):
6682class TimeToTimeStr(Func):
6683    pass
key = 'timetotimestr'
class TimeToUnix(Func):
6686class TimeToUnix(Func):
6687    pass
key = 'timetounix'
class TimeStrToDate(Func):
6690class TimeStrToDate(Func):
6691    pass
key = 'timestrtodate'
class TimeStrToTime(Func):
6694class TimeStrToTime(Func):
6695    arg_types = {"this": True, "zone": False}
arg_types = {'this': True, 'zone': False}
key = 'timestrtotime'
class TimeStrToUnix(Func):
6698class TimeStrToUnix(Func):
6699    pass
key = 'timestrtounix'
class Trim(Func):
6702class Trim(Func):
6703    arg_types = {
6704        "this": True,
6705        "expression": False,
6706        "position": False,
6707        "collation": False,
6708    }
arg_types = {'this': True, 'expression': False, 'position': False, 'collation': False}
key = 'trim'
class TsOrDsAdd(Func, TimeUnit):
6711class TsOrDsAdd(Func, TimeUnit):
6712    # return_type is used to correctly cast the arguments of this expression when transpiling it
6713    arg_types = {"this": True, "expression": True, "unit": False, "return_type": False}
6714
6715    @property
6716    def return_type(self) -> DataType:
6717        return DataType.build(self.args.get("return_type") or DataType.Type.DATE)
arg_types = {'this': True, 'expression': True, 'unit': False, 'return_type': False}
return_type: DataType
6715    @property
6716    def return_type(self) -> DataType:
6717        return DataType.build(self.args.get("return_type") or DataType.Type.DATE)
key = 'tsordsadd'
class TsOrDsDiff(Func, TimeUnit):
6720class TsOrDsDiff(Func, TimeUnit):
6721    arg_types = {"this": True, "expression": True, "unit": False}
arg_types = {'this': True, 'expression': True, 'unit': False}
key = 'tsordsdiff'
class TsOrDsToDateStr(Func):
6724class TsOrDsToDateStr(Func):
6725    pass
key = 'tsordstodatestr'
class TsOrDsToDate(Func):
6728class TsOrDsToDate(Func):
6729    arg_types = {"this": True, "format": False, "safe": False}
arg_types = {'this': True, 'format': False, 'safe': False}
key = 'tsordstodate'
class TsOrDsToDatetime(Func):
6732class TsOrDsToDatetime(Func):
6733    pass
key = 'tsordstodatetime'
class TsOrDsToTime(Func):
6736class TsOrDsToTime(Func):
6737    arg_types = {"this": True, "format": False, "safe": False}
arg_types = {'this': True, 'format': False, 'safe': False}
key = 'tsordstotime'
class TsOrDsToTimestamp(Func):
6740class TsOrDsToTimestamp(Func):
6741    pass
key = 'tsordstotimestamp'
class TsOrDiToDi(Func):
6744class TsOrDiToDi(Func):
6745    pass
key = 'tsorditodi'
class Unhex(Func):
6748class Unhex(Func):
6749    arg_types = {"this": True, "expression": False}
arg_types = {'this': True, 'expression': False}
key = 'unhex'
class Unicode(Func):
6752class Unicode(Func):
6753    pass
key = 'unicode'
class UnixDate(Func):
6757class UnixDate(Func):
6758    pass
key = 'unixdate'
class UnixToStr(Func):
6761class UnixToStr(Func):
6762    arg_types = {"this": True, "format": False}
arg_types = {'this': True, 'format': False}
key = 'unixtostr'
class UnixToTime(Func):
6767class UnixToTime(Func):
6768    arg_types = {
6769        "this": True,
6770        "scale": False,
6771        "zone": False,
6772        "hours": False,
6773        "minutes": False,
6774        "format": False,
6775    }
6776
6777    SECONDS = Literal.number(0)
6778    DECIS = Literal.number(1)
6779    CENTIS = Literal.number(2)
6780    MILLIS = Literal.number(3)
6781    DECIMILLIS = Literal.number(4)
6782    CENTIMILLIS = Literal.number(5)
6783    MICROS = Literal.number(6)
6784    DECIMICROS = Literal.number(7)
6785    CENTIMICROS = Literal.number(8)
6786    NANOS = Literal.number(9)
arg_types = {'this': True, 'scale': False, 'zone': False, 'hours': False, 'minutes': False, 'format': False}
SECONDS = Literal(this=0, is_string=False)
DECIS = Literal(this=1, is_string=False)
CENTIS = Literal(this=2, is_string=False)
MILLIS = Literal(this=3, is_string=False)
DECIMILLIS = Literal(this=4, is_string=False)
CENTIMILLIS = Literal(this=5, is_string=False)
MICROS = Literal(this=6, is_string=False)
DECIMICROS = Literal(this=7, is_string=False)
CENTIMICROS = Literal(this=8, is_string=False)
NANOS = Literal(this=9, is_string=False)
key = 'unixtotime'
class UnixToTimeStr(Func):
6789class UnixToTimeStr(Func):
6790    pass
key = 'unixtotimestr'
class UnixSeconds(Func):
6793class UnixSeconds(Func):
6794    pass
key = 'unixseconds'
class Uuid(Func):
6797class Uuid(Func):
6798    _sql_names = ["UUID", "GEN_RANDOM_UUID", "GENERATE_UUID", "UUID_STRING"]
6799
6800    arg_types = {"this": False, "name": False}
arg_types = {'this': False, 'name': False}
key = 'uuid'
class TimestampFromParts(Func):
6803class TimestampFromParts(Func):
6804    _sql_names = ["TIMESTAMP_FROM_PARTS", "TIMESTAMPFROMPARTS"]
6805    arg_types = {
6806        "year": True,
6807        "month": True,
6808        "day": True,
6809        "hour": True,
6810        "min": True,
6811        "sec": True,
6812        "nano": False,
6813        "zone": False,
6814        "milli": False,
6815    }
arg_types = {'year': True, 'month': True, 'day': True, 'hour': True, 'min': True, 'sec': True, 'nano': False, 'zone': False, 'milli': False}
key = 'timestampfromparts'
class Upper(Func):
6818class Upper(Func):
6819    _sql_names = ["UPPER", "UCASE"]
key = 'upper'
class Corr(Binary, AggFunc):
6822class Corr(Binary, AggFunc):
6823    pass
key = 'corr'
class Variance(AggFunc):
6826class Variance(AggFunc):
6827    _sql_names = ["VARIANCE", "VARIANCE_SAMP", "VAR_SAMP"]
key = 'variance'
class VariancePop(AggFunc):
6830class VariancePop(AggFunc):
6831    _sql_names = ["VARIANCE_POP", "VAR_POP"]
key = 'variancepop'
class CovarSamp(Binary, AggFunc):
6834class CovarSamp(Binary, AggFunc):
6835    pass
key = 'covarsamp'
class CovarPop(Binary, AggFunc):
6838class CovarPop(Binary, AggFunc):
6839    pass
key = 'covarpop'
class Week(Func):
6842class Week(Func):
6843    arg_types = {"this": True, "mode": False}
arg_types = {'this': True, 'mode': False}
key = 'week'
class XMLElement(Func):
6846class XMLElement(Func):
6847    _sql_names = ["XMLELEMENT"]
6848    arg_types = {"this": True, "expressions": False}
arg_types = {'this': True, 'expressions': False}
key = 'xmlelement'
class XMLTable(Func):
6851class XMLTable(Func):
6852    arg_types = {
6853        "this": True,
6854        "namespaces": False,
6855        "passing": False,
6856        "columns": False,
6857        "by_ref": False,
6858    }
arg_types = {'this': True, 'namespaces': False, 'passing': False, 'columns': False, 'by_ref': False}
key = 'xmltable'
class XMLNamespace(Expression):
6861class XMLNamespace(Expression):
6862    pass
key = 'xmlnamespace'
class Year(Func):
6865class Year(Func):
6866    pass
key = 'year'
class Use(Expression):
6869class Use(Expression):
6870    arg_types = {"this": False, "expressions": False, "kind": False}
arg_types = {'this': False, 'expressions': False, 'kind': False}
key = 'use'
class Merge(DML):
6873class Merge(DML):
6874    arg_types = {
6875        "this": True,
6876        "using": True,
6877        "on": True,
6878        "whens": True,
6879        "with": False,
6880        "returning": False,
6881    }
arg_types = {'this': True, 'using': True, 'on': True, 'whens': True, 'with': False, 'returning': False}
key = 'merge'
class When(Expression):
6884class When(Expression):
6885    arg_types = {"matched": True, "source": False, "condition": False, "then": True}
arg_types = {'matched': True, 'source': False, 'condition': False, 'then': True}
key = 'when'
class Whens(Expression):
6888class Whens(Expression):
6889    """Wraps around one or more WHEN [NOT] MATCHED [...] clauses."""
6890
6891    arg_types = {"expressions": True}

Wraps around one or more WHEN [NOT] MATCHED [...] clauses.

arg_types = {'expressions': True}
key = 'whens'
class NextValueFor(Func):
6896class NextValueFor(Func):
6897    arg_types = {"this": True, "order": False}
arg_types = {'this': True, 'order': False}
key = 'nextvaluefor'
class Semicolon(Expression):
6902class Semicolon(Expression):
6903    arg_types = {}
arg_types = {}
key = 'semicolon'
ALL_FUNCTIONS = [<class 'Abs'>, <class 'AddMonths'>, <class 'And'>, <class 'AnonymousAggFunc'>, <class 'AnyValue'>, <class 'Apply'>, <class 'ApproxDistinct'>, <class 'ApproxQuantile'>, <class 'ApproxTopK'>, <class 'ArgMax'>, <class 'ArgMin'>, <class 'Array'>, <class 'ArrayAgg'>, <class 'ArrayAll'>, <class 'ArrayAny'>, <class 'ArrayConcat'>, <class 'ArrayConstructCompact'>, <class 'ArrayContains'>, <class 'ArrayContainsAll'>, <class 'ArrayFilter'>, <class 'ArrayOverlaps'>, <class 'ArraySize'>, <class 'ArraySort'>, <class 'ArraySum'>, <class 'ArrayToString'>, <class 'ArrayUnionAgg'>, <class 'ArrayUniqueAgg'>, <class 'Avg'>, <class 'Case'>, <class 'Cast'>, <class 'CastToStrType'>, <class 'Cbrt'>, <class 'Ceil'>, <class 'Chr'>, <class 'Coalesce'>, <class 'Collate'>, <class 'Columns'>, <class 'CombinedAggFunc'>, <class 'CombinedParameterizedAgg'>, <class 'Concat'>, <class 'ConcatWs'>, <class 'ConnectByRoot'>, <class 'Contains'>, <class 'Convert'>, <class 'ConvertTimezone'>, <class 'Corr'>, <class 'Count'>, <class 'CountIf'>, <class 'CovarPop'>, <class 'CovarSamp'>, <class 'CurrentDate'>, <class 'CurrentDatetime'>, <class 'CurrentSchema'>, <class 'CurrentTime'>, <class 'CurrentTimestamp'>, <class 'CurrentUser'>, <class 'Date'>, <class 'DateAdd'>, <class 'DateBin'>, <class 'DateDiff'>, <class 'DateFromParts'>, <class 'DateStrToDate'>, <class 'DateSub'>, <class 'DateToDateStr'>, <class 'DateToDi'>, <class 'DateTrunc'>, <class 'Datetime'>, <class 'DatetimeAdd'>, <class 'DatetimeDiff'>, <class 'DatetimeSub'>, <class 'DatetimeTrunc'>, <class 'Day'>, <class 'DayOfMonth'>, <class 'DayOfWeek'>, <class 'DayOfWeekIso'>, <class 'DayOfYear'>, <class 'Decode'>, <class 'DiToDate'>, <class 'Encode'>, <class 'Exists'>, <class 'Exp'>, <class 'Explode'>, <class 'ExplodeOuter'>, <class 'ExplodingGenerateSeries'>, <class 'Extract'>, <class 'FeaturesAtTime'>, <class 'First'>, <class 'FirstValue'>, <class 'Flatten'>, <class 'Floor'>, <class 'FromBase'>, <class 'FromBase64'>, <class 'FromISO8601Timestamp'>, <class 'GapFill'>, <class 'GenerateDateArray'>, <class 'GenerateSeries'>, <class 'GenerateTimestampArray'>, <class 'Greatest'>, <class 'GroupConcat'>, <class 'Hex'>, <class 'Hll'>, <class 'If'>, <class 'Initcap'>, <class 'Inline'>, <class 'Int64'>, <class 'IsAscii'>, <class 'IsInf'>, <class 'IsNan'>, <class 'JSONArray'>, <class 'JSONArrayAgg'>, <class 'JSONArrayContains'>, <class 'JSONBContains'>, <class 'JSONBExists'>, <class 'JSONBExtract'>, <class 'JSONBExtractScalar'>, <class 'JSONBObjectAgg'>, <class 'JSONCast'>, <class 'JSONExists'>, <class 'JSONExtract'>, <class 'JSONExtractArray'>, <class 'JSONExtractScalar'>, <class 'JSONFormat'>, <class 'JSONObject'>, <class 'JSONObjectAgg'>, <class 'JSONTable'>, <class 'JSONValueArray'>, <class 'Lag'>, <class 'Last'>, <class 'LastDay'>, <class 'LastValue'>, <class 'Lead'>, <class 'Least'>, <class 'Left'>, <class 'Length'>, <class 'Levenshtein'>, <class 'List'>, <class 'Ln'>, <class 'Log'>, <class 'LogicalAnd'>, <class 'LogicalOr'>, <class 'Lower'>, <class 'LowerHex'>, <class 'MD5'>, <class 'MD5Digest'>, <class 'MakeInterval'>, <class 'Map'>, <class 'MapFromEntries'>, <class 'MatchAgainst'>, <class 'Max'>, <class 'Median'>, <class 'Min'>, <class 'Month'>, <class 'MonthsBetween'>, <class 'NextValueFor'>, <class 'Normalize'>, <class 'NthValue'>, <class 'Nullif'>, <class 'NumberToStr'>, <class 'Nvl2'>, <class 'ObjectInsert'>, <class 'OpenJSON'>, <class 'Or'>, <class 'Overlay'>, <class 'Pad'>, <class 'ParameterizedAgg'>, <class 'ParseJSON'>, <class 'PercentileCont'>, <class 'PercentileDisc'>, <class 'Posexplode'>, <class 'PosexplodeOuter'>, <class 'Pow'>, <class 'Predict'>, <class 'Quantile'>, <class 'Quarter'>, <class 'Rand'>, <class 'Randn'>, <class 'RangeN'>, <class 'ReadCSV'>, <class 'Reduce'>, <class 'RegexpExtract'>, <class 'RegexpExtractAll'>, <class 'RegexpILike'>, <class 'RegexpLike'>, <class 'RegexpReplace'>, <class 'RegexpSplit'>, <class 'Repeat'>, <class 'Right'>, <class 'Round'>, <class 'RowNumber'>, <class 'SHA'>, <class 'SHA2'>, <class 'SafeDivide'>, <class 'Sign'>, <class 'SortArray'>, <class 'Split'>, <class 'SplitPart'>, <class 'Sqrt'>, <class 'StandardHash'>, <class 'StarMap'>, <class 'StartsWith'>, <class 'Stddev'>, <class 'StddevPop'>, <class 'StddevSamp'>, <class 'StrPosition'>, <class 'StrToDate'>, <class 'StrToMap'>, <class 'StrToTime'>, <class 'StrToUnix'>, <class 'String'>, <class 'StringToArray'>, <class 'Struct'>, <class 'StructExtract'>, <class 'Stuff'>, <class 'Substring'>, <class 'Sum'>, <class 'Time'>, <class 'TimeAdd'>, <class 'TimeDiff'>, <class 'TimeFromParts'>, <class 'TimeStrToDate'>, <class 'TimeStrToTime'>, <class 'TimeStrToUnix'>, <class 'TimeSub'>, <class 'TimeToStr'>, <class 'TimeToTimeStr'>, <class 'TimeToUnix'>, <class 'TimeTrunc'>, <class 'Timestamp'>, <class 'TimestampAdd'>, <class 'TimestampDiff'>, <class 'TimestampFromParts'>, <class 'TimestampSub'>, <class 'TimestampTrunc'>, <class 'ToArray'>, <class 'ToBase64'>, <class 'ToChar'>, <class 'ToDays'>, <class 'ToDouble'>, <class 'ToMap'>, <class 'ToNumber'>, <class 'Transform'>, <class 'Trim'>, <class 'Try'>, <class 'TryCast'>, <class 'TsOrDiToDi'>, <class 'TsOrDsAdd'>, <class 'TsOrDsDiff'>, <class 'TsOrDsToDate'>, <class 'TsOrDsToDateStr'>, <class 'TsOrDsToDatetime'>, <class 'TsOrDsToTime'>, <class 'TsOrDsToTimestamp'>, <class 'Unhex'>, <class 'Unicode'>, <class 'UnixDate'>, <class 'UnixSeconds'>, <class 'UnixToStr'>, <class 'UnixToTime'>, <class 'UnixToTimeStr'>, <class 'Unnest'>, <class 'Upper'>, <class 'Uuid'>, <class 'VarMap'>, <class 'Variance'>, <class 'VariancePop'>, <class 'Week'>, <class 'WeekOfYear'>, <class 'XMLElement'>, <class 'XMLTable'>, <class 'Xor'>, <class 'Year'>]
FUNCTION_BY_NAME = {'ABS': <class 'Abs'>, 'ADD_MONTHS': <class 'AddMonths'>, 'AND': <class 'And'>, 'ANONYMOUS_AGG_FUNC': <class 'AnonymousAggFunc'>, 'ANY_VALUE': <class 'AnyValue'>, 'APPLY': <class 'Apply'>, 'APPROX_DISTINCT': <class 'ApproxDistinct'>, 'APPROX_COUNT_DISTINCT': <class 'ApproxDistinct'>, 'APPROX_QUANTILE': <class 'ApproxQuantile'>, 'APPROX_TOP_K': <class 'ApproxTopK'>, 'ARG_MAX': <class 'ArgMax'>, 'ARGMAX': <class 'ArgMax'>, 'MAX_BY': <class 'ArgMax'>, 'ARG_MIN': <class 'ArgMin'>, 'ARGMIN': <class 'ArgMin'>, 'MIN_BY': <class 'ArgMin'>, 'ARRAY': <class 'Array'>, 'ARRAY_AGG': <class 'ArrayAgg'>, 'ARRAY_ALL': <class 'ArrayAll'>, 'ARRAY_ANY': <class 'ArrayAny'>, 'ARRAY_CONCAT': <class 'ArrayConcat'>, 'ARRAY_CAT': <class 'ArrayConcat'>, 'ARRAY_CONSTRUCT_COMPACT': <class 'ArrayConstructCompact'>, 'ARRAY_CONTAINS': <class 'ArrayContains'>, 'ARRAY_HAS': <class 'ArrayContains'>, 'ARRAY_CONTAINS_ALL': <class 'ArrayContainsAll'>, 'ARRAY_HAS_ALL': <class 'ArrayContainsAll'>, 'FILTER': <class 'ArrayFilter'>, 'ARRAY_FILTER': <class 'ArrayFilter'>, 'ARRAY_OVERLAPS': <class 'ArrayOverlaps'>, 'ARRAY_SIZE': <class 'ArraySize'>, 'ARRAY_LENGTH': <class 'ArraySize'>, 'ARRAY_SORT': <class 'ArraySort'>, 'ARRAY_SUM': <class 'ArraySum'>, 'ARRAY_TO_STRING': <class 'ArrayToString'>, 'ARRAY_JOIN': <class 'ArrayToString'>, 'ARRAY_UNION_AGG': <class 'ArrayUnionAgg'>, 'ARRAY_UNIQUE_AGG': <class 'ArrayUniqueAgg'>, 'AVG': <class 'Avg'>, 'CASE': <class 'Case'>, 'CAST': <class 'Cast'>, 'CAST_TO_STR_TYPE': <class 'CastToStrType'>, 'CBRT': <class 'Cbrt'>, 'CEIL': <class 'Ceil'>, 'CEILING': <class 'Ceil'>, 'CHR': <class 'Chr'>, 'CHAR': <class 'Chr'>, 'COALESCE': <class 'Coalesce'>, 'IFNULL': <class 'Coalesce'>, 'NVL': <class 'Coalesce'>, 'COLLATE': <class 'Collate'>, 'COLUMNS': <class 'Columns'>, 'COMBINED_AGG_FUNC': <class 'CombinedAggFunc'>, 'COMBINED_PARAMETERIZED_AGG': <class 'CombinedParameterizedAgg'>, 'CONCAT': <class 'Concat'>, 'CONCAT_WS': <class 'ConcatWs'>, 'CONNECT_BY_ROOT': <class 'ConnectByRoot'>, 'CONTAINS': <class 'Contains'>, 'CONVERT': <class 'Convert'>, 'CONVERT_TIMEZONE': <class 'ConvertTimezone'>, 'CORR': <class 'Corr'>, 'COUNT': <class 'Count'>, 'COUNT_IF': <class 'CountIf'>, 'COUNTIF': <class 'CountIf'>, 'COVAR_POP': <class 'CovarPop'>, 'COVAR_SAMP': <class 'CovarSamp'>, 'CURRENT_DATE': <class 'CurrentDate'>, 'CURRENT_DATETIME': <class 'CurrentDatetime'>, 'CURRENT_SCHEMA': <class 'CurrentSchema'>, 'CURRENT_TIME': <class 'CurrentTime'>, 'CURRENT_TIMESTAMP': <class 'CurrentTimestamp'>, 'CURRENT_USER': <class 'CurrentUser'>, 'DATE': <class 'Date'>, 'DATE_ADD': <class 'DateAdd'>, 'DATE_BIN': <class 'DateBin'>, 'DATEDIFF': <class 'DateDiff'>, 'DATE_DIFF': <class 'DateDiff'>, 'DATE_FROM_PARTS': <class 'DateFromParts'>, 'DATEFROMPARTS': <class 'DateFromParts'>, 'DATE_STR_TO_DATE': <class 'DateStrToDate'>, 'DATE_SUB': <class 'DateSub'>, 'DATE_TO_DATE_STR': <class 'DateToDateStr'>, 'DATE_TO_DI': <class 'DateToDi'>, 'DATE_TRUNC': <class 'DateTrunc'>, 'DATETIME': <class 'Datetime'>, 'DATETIME_ADD': <class 'DatetimeAdd'>, 'DATETIME_DIFF': <class 'DatetimeDiff'>, 'DATETIME_SUB': <class 'DatetimeSub'>, 'DATETIME_TRUNC': <class 'DatetimeTrunc'>, 'DAY': <class 'Day'>, 'DAY_OF_MONTH': <class 'DayOfMonth'>, 'DAYOFMONTH': <class 'DayOfMonth'>, 'DAY_OF_WEEK': <class 'DayOfWeek'>, 'DAYOFWEEK': <class 'DayOfWeek'>, 'DAYOFWEEK_ISO': <class 'DayOfWeekIso'>, 'ISODOW': <class 'DayOfWeekIso'>, 'DAY_OF_YEAR': <class 'DayOfYear'>, 'DAYOFYEAR': <class 'DayOfYear'>, 'DECODE': <class 'Decode'>, 'DI_TO_DATE': <class 'DiToDate'>, 'ENCODE': <class 'Encode'>, 'EXISTS': <class 'Exists'>, 'EXP': <class 'Exp'>, 'EXPLODE': <class 'Explode'>, 'EXPLODE_OUTER': <class 'ExplodeOuter'>, 'EXPLODING_GENERATE_SERIES': <class 'ExplodingGenerateSeries'>, 'EXTRACT': <class 'Extract'>, 'FEATURES_AT_TIME': <class 'FeaturesAtTime'>, 'FIRST': <class 'First'>, 'FIRST_VALUE': <class 'FirstValue'>, 'FLATTEN': <class 'Flatten'>, 'FLOOR': <class 'Floor'>, 'FROM_BASE': <class 'FromBase'>, 'FROM_BASE64': <class 'FromBase64'>, 'FROM_ISO8601_TIMESTAMP': <class 'FromISO8601Timestamp'>, 'GAP_FILL': <class 'GapFill'>, 'GENERATE_DATE_ARRAY': <class 'GenerateDateArray'>, 'GENERATE_SERIES': <class 'GenerateSeries'>, 'GENERATE_TIMESTAMP_ARRAY': <class 'GenerateTimestampArray'>, 'GREATEST': <class 'Greatest'>, 'GROUP_CONCAT': <class 'GroupConcat'>, 'HEX': <class 'Hex'>, 'HLL': <class 'Hll'>, 'IF': <class 'If'>, 'IIF': <class 'If'>, 'INITCAP': <class 'Initcap'>, 'INLINE': <class 'Inline'>, 'INT64': <class 'Int64'>, 'IS_ASCII': <class 'IsAscii'>, 'IS_INF': <class 'IsInf'>, 'ISINF': <class 'IsInf'>, 'IS_NAN': <class 'IsNan'>, 'ISNAN': <class 'IsNan'>, 'J_S_O_N_ARRAY': <class 'JSONArray'>, 'J_S_O_N_ARRAY_AGG': <class 'JSONArrayAgg'>, 'JSON_ARRAY_CONTAINS': <class 'JSONArrayContains'>, 'JSONB_CONTAINS': <class 'JSONBContains'>, 'JSONB_EXISTS': <class 'JSONBExists'>, 'JSONB_EXTRACT': <class 'JSONBExtract'>, 'JSONB_EXTRACT_SCALAR': <class 'JSONBExtractScalar'>, 'J_S_O_N_B_OBJECT_AGG': <class 'JSONBObjectAgg'>, 'J_S_O_N_CAST': <class 'JSONCast'>, 'J_S_O_N_EXISTS': <class 'JSONExists'>, 'JSON_EXTRACT': <class 'JSONExtract'>, 'JSON_EXTRACT_ARRAY': <class 'JSONExtractArray'>, 'JSON_EXTRACT_SCALAR': <class 'JSONExtractScalar'>, 'JSON_FORMAT': <class 'JSONFormat'>, 'J_S_O_N_OBJECT': <class 'JSONObject'>, 'J_S_O_N_OBJECT_AGG': <class 'JSONObjectAgg'>, 'J_S_O_N_TABLE': <class 'JSONTable'>, 'J_S_O_N_VALUE_ARRAY': <class 'JSONValueArray'>, 'LAG': <class 'Lag'>, 'LAST': <class 'Last'>, 'LAST_DAY': <class 'LastDay'>, 'LAST_DAY_OF_MONTH': <class 'LastDay'>, 'LAST_VALUE': <class 'LastValue'>, 'LEAD': <class 'Lead'>, 'LEAST': <class 'Least'>, 'LEFT': <class 'Left'>, 'LENGTH': <class 'Length'>, 'LEN': <class 'Length'>, 'CHAR_LENGTH': <class 'Length'>, 'CHARACTER_LENGTH': <class 'Length'>, 'LEVENSHTEIN': <class 'Levenshtein'>, 'LIST': <class 'List'>, 'LN': <class 'Ln'>, 'LOG': <class 'Log'>, 'LOGICAL_AND': <class 'LogicalAnd'>, 'BOOL_AND': <class 'LogicalAnd'>, 'BOOLAND_AGG': <class 'LogicalAnd'>, 'LOGICAL_OR': <class 'LogicalOr'>, 'BOOL_OR': <class 'LogicalOr'>, 'BOOLOR_AGG': <class 'LogicalOr'>, 'LOWER': <class 'Lower'>, 'LCASE': <class 'Lower'>, 'LOWER_HEX': <class 'LowerHex'>, 'MD5': <class 'MD5'>, 'MD5_DIGEST': <class 'MD5Digest'>, 'MAKE_INTERVAL': <class 'MakeInterval'>, 'MAP': <class 'Map'>, 'MAP_FROM_ENTRIES': <class 'MapFromEntries'>, 'MATCH_AGAINST': <class 'MatchAgainst'>, 'MAX': <class 'Max'>, 'MEDIAN': <class 'Median'>, 'MIN': <class 'Min'>, 'MONTH': <class 'Month'>, 'MONTHS_BETWEEN': <class 'MonthsBetween'>, 'NEXT_VALUE_FOR': <class 'NextValueFor'>, 'NORMALIZE': <class 'Normalize'>, 'NTH_VALUE': <class 'NthValue'>, 'NULLIF': <class 'Nullif'>, 'NUMBER_TO_STR': <class 'NumberToStr'>, 'NVL2': <class 'Nvl2'>, 'OBJECT_INSERT': <class 'ObjectInsert'>, 'OPEN_J_S_O_N': <class 'OpenJSON'>, 'OR': <class 'Or'>, 'OVERLAY': <class 'Overlay'>, 'PAD': <class 'Pad'>, 'PARAMETERIZED_AGG': <class 'ParameterizedAgg'>, 'PARSE_JSON': <class 'ParseJSON'>, 'JSON_PARSE': <class 'ParseJSON'>, 'PERCENTILE_CONT': <class 'PercentileCont'>, 'PERCENTILE_DISC': <class 'PercentileDisc'>, 'POSEXPLODE': <class 'Posexplode'>, 'POSEXPLODE_OUTER': <class 'PosexplodeOuter'>, 'POWER': <class 'Pow'>, 'POW': <class 'Pow'>, 'PREDICT': <class 'Predict'>, 'QUANTILE': <class 'Quantile'>, 'QUARTER': <class 'Quarter'>, 'RAND': <class 'Rand'>, 'RANDOM': <class 'Rand'>, 'RANDN': <class 'Randn'>, 'RANGE_N': <class 'RangeN'>, 'READ_CSV': <class 'ReadCSV'>, 'REDUCE': <class 'Reduce'>, 'REGEXP_EXTRACT': <class 'RegexpExtract'>, 'REGEXP_EXTRACT_ALL': <class 'RegexpExtractAll'>, 'REGEXP_I_LIKE': <class 'RegexpILike'>, 'REGEXP_LIKE': <class 'RegexpLike'>, 'REGEXP_REPLACE': <class 'RegexpReplace'>, 'REGEXP_SPLIT': <class 'RegexpSplit'>, 'REPEAT': <class 'Repeat'>, 'RIGHT': <class 'Right'>, 'ROUND': <class 'Round'>, 'ROW_NUMBER': <class 'RowNumber'>, 'SHA': <class 'SHA'>, 'SHA1': <class 'SHA'>, 'SHA2': <class 'SHA2'>, 'SAFE_DIVIDE': <class 'SafeDivide'>, 'SIGN': <class 'Sign'>, 'SIGNUM': <class 'Sign'>, 'SORT_ARRAY': <class 'SortArray'>, 'SPLIT': <class 'Split'>, 'SPLIT_PART': <class 'SplitPart'>, 'SQRT': <class 'Sqrt'>, 'STANDARD_HASH': <class 'StandardHash'>, 'STAR_MAP': <class 'StarMap'>, 'STARTS_WITH': <class 'StartsWith'>, 'STARTSWITH': <class 'StartsWith'>, 'STDDEV': <class 'Stddev'>, 'STDEV': <class 'Stddev'>, 'STDDEV_POP': <class 'StddevPop'>, 'STDDEV_SAMP': <class 'StddevSamp'>, 'STR_POSITION': <class 'StrPosition'>, 'STR_TO_DATE': <class 'StrToDate'>, 'STR_TO_MAP': <class 'StrToMap'>, 'STR_TO_TIME': <class 'StrToTime'>, 'STR_TO_UNIX': <class 'StrToUnix'>, 'STRING': <class 'String'>, 'STRING_TO_ARRAY': <class 'StringToArray'>, 'SPLIT_BY_STRING': <class 'StringToArray'>, 'STRUCT': <class 'Struct'>, 'STRUCT_EXTRACT': <class 'StructExtract'>, 'STUFF': <class 'Stuff'>, 'INSERT': <class 'Stuff'>, 'SUBSTRING': <class 'Substring'>, 'SUBSTR': <class 'Substring'>, 'SUM': <class 'Sum'>, 'TIME': <class 'Time'>, 'TIME_ADD': <class 'TimeAdd'>, 'TIME_DIFF': <class 'TimeDiff'>, 'TIME_FROM_PARTS': <class 'TimeFromParts'>, 'TIMEFROMPARTS': <class 'TimeFromParts'>, 'TIME_STR_TO_DATE': <class 'TimeStrToDate'>, 'TIME_STR_TO_TIME': <class 'TimeStrToTime'>, 'TIME_STR_TO_UNIX': <class 'TimeStrToUnix'>, 'TIME_SUB': <class 'TimeSub'>, 'TIME_TO_STR': <class 'TimeToStr'>, 'TIME_TO_TIME_STR': <class 'TimeToTimeStr'>, 'TIME_TO_UNIX': <class 'TimeToUnix'>, 'TIME_TRUNC': <class 'TimeTrunc'>, 'TIMESTAMP': <class 'Timestamp'>, 'TIMESTAMP_ADD': <class 'TimestampAdd'>, 'TIMESTAMPDIFF': <class 'TimestampDiff'>, 'TIMESTAMP_DIFF': <class 'TimestampDiff'>, 'TIMESTAMP_FROM_PARTS': <class 'TimestampFromParts'>, 'TIMESTAMPFROMPARTS': <class 'TimestampFromParts'>, 'TIMESTAMP_SUB': <class 'TimestampSub'>, 'TIMESTAMP_TRUNC': <class 'TimestampTrunc'>, 'TO_ARRAY': <class 'ToArray'>, 'TO_BASE64': <class 'ToBase64'>, 'TO_CHAR': <class 'ToChar'>, 'TO_DAYS': <class 'ToDays'>, 'TO_DOUBLE': <class 'ToDouble'>, 'TO_MAP': <class 'ToMap'>, 'TO_NUMBER': <class 'ToNumber'>, 'TRANSFORM': <class 'Transform'>, 'TRIM': <class 'Trim'>, 'TRY': <class 'Try'>, 'TRY_CAST': <class 'TryCast'>, 'TS_OR_DI_TO_DI': <class 'TsOrDiToDi'>, 'TS_OR_DS_ADD': <class 'TsOrDsAdd'>, 'TS_OR_DS_DIFF': <class 'TsOrDsDiff'>, 'TS_OR_DS_TO_DATE': <class 'TsOrDsToDate'>, 'TS_OR_DS_TO_DATE_STR': <class 'TsOrDsToDateStr'>, 'TS_OR_DS_TO_DATETIME': <class 'TsOrDsToDatetime'>, 'TS_OR_DS_TO_TIME': <class 'TsOrDsToTime'>, 'TS_OR_DS_TO_TIMESTAMP': <class 'TsOrDsToTimestamp'>, 'UNHEX': <class 'Unhex'>, 'UNICODE': <class 'Unicode'>, 'UNIX_DATE': <class 'UnixDate'>, 'UNIX_SECONDS': <class 'UnixSeconds'>, 'UNIX_TO_STR': <class 'UnixToStr'>, 'UNIX_TO_TIME': <class 'UnixToTime'>, 'UNIX_TO_TIME_STR': <class 'UnixToTimeStr'>, 'UNNEST': <class 'Unnest'>, 'UPPER': <class 'Upper'>, 'UCASE': <class 'Upper'>, 'UUID': <class 'Uuid'>, 'GEN_RANDOM_UUID': <class 'Uuid'>, 'GENERATE_UUID': <class 'Uuid'>, 'UUID_STRING': <class 'Uuid'>, 'VAR_MAP': <class 'VarMap'>, 'VARIANCE': <class 'Variance'>, 'VARIANCE_SAMP': <class 'Variance'>, 'VAR_SAMP': <class 'Variance'>, 'VARIANCE_POP': <class 'VariancePop'>, 'VAR_POP': <class 'VariancePop'>, 'WEEK': <class 'Week'>, 'WEEK_OF_YEAR': <class 'WeekOfYear'>, 'WEEKOFYEAR': <class 'WeekOfYear'>, 'XMLELEMENT': <class 'XMLElement'>, 'X_M_L_TABLE': <class 'XMLTable'>, 'XOR': <class 'Xor'>, 'YEAR': <class 'Year'>}
JSON_PATH_PARTS = [<class 'JSONPathFilter'>, <class 'JSONPathKey'>, <class 'JSONPathRecursive'>, <class 'JSONPathRoot'>, <class 'JSONPathScript'>, <class 'JSONPathSelector'>, <class 'JSONPathSlice'>, <class 'JSONPathSubscript'>, <class 'JSONPathUnion'>, <class 'JSONPathWildcard'>]
PERCENTILES = (<class 'PercentileCont'>, <class 'PercentileDisc'>)
def maybe_parse( sql_or_expression: Union[str, Expression], *, into: Union[str, Type[Expression], Collection[Union[str, Type[Expression]]], NoneType] = None, dialect: Union[str, sqlglot.dialects.Dialect, Type[sqlglot.dialects.Dialect], NoneType] = None, prefix: Optional[str] = None, copy: bool = False, **opts) -> Expression:
6943def maybe_parse(
6944    sql_or_expression: ExpOrStr,
6945    *,
6946    into: t.Optional[IntoType] = None,
6947    dialect: DialectType = None,
6948    prefix: t.Optional[str] = None,
6949    copy: bool = False,
6950    **opts,
6951) -> Expression:
6952    """Gracefully handle a possible string or expression.
6953
6954    Example:
6955        >>> maybe_parse("1")
6956        Literal(this=1, is_string=False)
6957        >>> maybe_parse(to_identifier("x"))
6958        Identifier(this=x, quoted=False)
6959
6960    Args:
6961        sql_or_expression: the SQL code string or an expression
6962        into: the SQLGlot Expression to parse into
6963        dialect: the dialect used to parse the input expressions (in the case that an
6964            input expression is a SQL string).
6965        prefix: a string to prefix the sql with before it gets parsed
6966            (automatically includes a space)
6967        copy: whether to copy the expression.
6968        **opts: other options to use to parse the input expressions (again, in the case
6969            that an input expression is a SQL string).
6970
6971    Returns:
6972        Expression: the parsed or given expression.
6973    """
6974    if isinstance(sql_or_expression, Expression):
6975        if copy:
6976            return sql_or_expression.copy()
6977        return sql_or_expression
6978
6979    if sql_or_expression is None:
6980        raise ParseError("SQL cannot be None")
6981
6982    import sqlglot
6983
6984    sql = str(sql_or_expression)
6985    if prefix:
6986        sql = f"{prefix} {sql}"
6987
6988    return sqlglot.parse_one(sql, read=dialect, into=into, **opts)

Gracefully handle a possible string or expression.

Example:
>>> maybe_parse("1")
Literal(this=1, is_string=False)
>>> maybe_parse(to_identifier("x"))
Identifier(this=x, quoted=False)
Arguments:
  • sql_or_expression: the SQL code string or an expression
  • into: the SQLGlot Expression to parse into
  • dialect: the dialect used to parse the input expressions (in the case that an input expression is a SQL string).
  • prefix: a string to prefix the sql with before it gets parsed (automatically includes a space)
  • copy: whether to copy the expression.
  • **opts: other options to use to parse the input expressions (again, in the case that an input expression is a SQL string).
Returns:

Expression: the parsed or given expression.

def maybe_copy(instance, copy=True):
6999def maybe_copy(instance, copy=True):
7000    return instance.copy() if copy and instance else instance
def union( *expressions: Union[str, Expression], distinct: bool = True, dialect: Union[str, sqlglot.dialects.Dialect, Type[sqlglot.dialects.Dialect], NoneType] = None, copy: bool = True, **opts) -> Union:
7248def union(
7249    *expressions: ExpOrStr,
7250    distinct: bool = True,
7251    dialect: DialectType = None,
7252    copy: bool = True,
7253    **opts,
7254) -> Union:
7255    """
7256    Initializes a syntax tree for the `UNION` operation.
7257
7258    Example:
7259        >>> union("SELECT * FROM foo", "SELECT * FROM bla").sql()
7260        'SELECT * FROM foo UNION SELECT * FROM bla'
7261
7262    Args:
7263        expressions: the SQL code strings, corresponding to the `UNION`'s operands.
7264            If `Expression` instances are passed, they will be used as-is.
7265        distinct: set the DISTINCT flag if and only if this is true.
7266        dialect: the dialect used to parse the input expression.
7267        copy: whether to copy the expression.
7268        opts: other options to use to parse the input expressions.
7269
7270    Returns:
7271        The new Union instance.
7272    """
7273    assert len(expressions) >= 2, "At least two expressions are required by `union`."
7274    return _apply_set_operation(
7275        *expressions, set_operation=Union, distinct=distinct, dialect=dialect, copy=copy, **opts
7276    )

Initializes a syntax tree for the UNION operation.

Example:
>>> union("SELECT * FROM foo", "SELECT * FROM bla").sql()
'SELECT * FROM foo UNION SELECT * FROM bla'
Arguments:
  • expressions: the SQL code strings, corresponding to the UNION's operands. If Expression instances are passed, they will be used as-is.
  • distinct: set the DISTINCT flag if and only if this is true.
  • dialect: the dialect used to parse the input expression.
  • copy: whether to copy the expression.
  • opts: other options to use to parse the input expressions.
Returns:

The new Union instance.

def intersect( *expressions: Union[str, Expression], distinct: bool = True, dialect: Union[str, sqlglot.dialects.Dialect, Type[sqlglot.dialects.Dialect], NoneType] = None, copy: bool = True, **opts) -> Intersect:
7279def intersect(
7280    *expressions: ExpOrStr,
7281    distinct: bool = True,
7282    dialect: DialectType = None,
7283    copy: bool = True,
7284    **opts,
7285) -> Intersect:
7286    """
7287    Initializes a syntax tree for the `INTERSECT` operation.
7288
7289    Example:
7290        >>> intersect("SELECT * FROM foo", "SELECT * FROM bla").sql()
7291        'SELECT * FROM foo INTERSECT SELECT * FROM bla'
7292
7293    Args:
7294        expressions: the SQL code strings, corresponding to the `INTERSECT`'s operands.
7295            If `Expression` instances are passed, they will be used as-is.
7296        distinct: set the DISTINCT flag if and only if this is true.
7297        dialect: the dialect used to parse the input expression.
7298        copy: whether to copy the expression.
7299        opts: other options to use to parse the input expressions.
7300
7301    Returns:
7302        The new Intersect instance.
7303    """
7304    assert len(expressions) >= 2, "At least two expressions are required by `intersect`."
7305    return _apply_set_operation(
7306        *expressions, set_operation=Intersect, distinct=distinct, dialect=dialect, copy=copy, **opts
7307    )

Initializes a syntax tree for the INTERSECT operation.

Example:
>>> intersect("SELECT * FROM foo", "SELECT * FROM bla").sql()
'SELECT * FROM foo INTERSECT SELECT * FROM bla'
Arguments:
  • expressions: the SQL code strings, corresponding to the INTERSECT's operands. If Expression instances are passed, they will be used as-is.
  • distinct: set the DISTINCT flag if and only if this is true.
  • dialect: the dialect used to parse the input expression.
  • copy: whether to copy the expression.
  • opts: other options to use to parse the input expressions.
Returns:

The new Intersect instance.

def except_( *expressions: Union[str, Expression], distinct: bool = True, dialect: Union[str, sqlglot.dialects.Dialect, Type[sqlglot.dialects.Dialect], NoneType] = None, copy: bool = True, **opts) -> Except:
7310def except_(
7311    *expressions: ExpOrStr,
7312    distinct: bool = True,
7313    dialect: DialectType = None,
7314    copy: bool = True,
7315    **opts,
7316) -> Except:
7317    """
7318    Initializes a syntax tree for the `EXCEPT` operation.
7319
7320    Example:
7321        >>> except_("SELECT * FROM foo", "SELECT * FROM bla").sql()
7322        'SELECT * FROM foo EXCEPT SELECT * FROM bla'
7323
7324    Args:
7325        expressions: the SQL code strings, corresponding to the `EXCEPT`'s operands.
7326            If `Expression` instances are passed, they will be used as-is.
7327        distinct: set the DISTINCT flag if and only if this is true.
7328        dialect: the dialect used to parse the input expression.
7329        copy: whether to copy the expression.
7330        opts: other options to use to parse the input expressions.
7331
7332    Returns:
7333        The new Except instance.
7334    """
7335    assert len(expressions) >= 2, "At least two expressions are required by `except_`."
7336    return _apply_set_operation(
7337        *expressions, set_operation=Except, distinct=distinct, dialect=dialect, copy=copy, **opts
7338    )

Initializes a syntax tree for the EXCEPT operation.

Example:
>>> except_("SELECT * FROM foo", "SELECT * FROM bla").sql()
'SELECT * FROM foo EXCEPT SELECT * FROM bla'
Arguments:
  • expressions: the SQL code strings, corresponding to the EXCEPT's operands. If Expression instances are passed, they will be used as-is.
  • distinct: set the DISTINCT flag if and only if this is true.
  • dialect: the dialect used to parse the input expression.
  • copy: whether to copy the expression.
  • opts: other options to use to parse the input expressions.
Returns:

The new Except instance.

def select( *expressions: Union[str, Expression], dialect: Union[str, sqlglot.dialects.Dialect, Type[sqlglot.dialects.Dialect], NoneType] = None, **opts) -> Select:
7341def select(*expressions: ExpOrStr, dialect: DialectType = None, **opts) -> Select:
7342    """
7343    Initializes a syntax tree from one or multiple SELECT expressions.
7344
7345    Example:
7346        >>> select("col1", "col2").from_("tbl").sql()
7347        'SELECT col1, col2 FROM tbl'
7348
7349    Args:
7350        *expressions: the SQL code string to parse as the expressions of a
7351            SELECT statement. If an Expression instance is passed, this is used as-is.
7352        dialect: the dialect used to parse the input expressions (in the case that an
7353            input expression is a SQL string).
7354        **opts: other options to use to parse the input expressions (again, in the case
7355            that an input expression is a SQL string).
7356
7357    Returns:
7358        Select: the syntax tree for the SELECT statement.
7359    """
7360    return Select().select(*expressions, dialect=dialect, **opts)

Initializes a syntax tree from one or multiple SELECT expressions.

Example:
>>> select("col1", "col2").from_("tbl").sql()
'SELECT col1, col2 FROM tbl'
Arguments:
  • *expressions: the SQL code string to parse as the expressions of a SELECT statement. If an Expression instance is passed, this is used as-is.
  • dialect: the dialect used to parse the input expressions (in the case that an input expression is a SQL string).
  • **opts: other options to use to parse the input expressions (again, in the case that an input expression is a SQL string).
Returns:

Select: the syntax tree for the SELECT statement.

def from_( expression: Union[str, Expression], dialect: Union[str, sqlglot.dialects.Dialect, Type[sqlglot.dialects.Dialect], NoneType] = None, **opts) -> Select:
7363def from_(expression: ExpOrStr, dialect: DialectType = None, **opts) -> Select:
7364    """
7365    Initializes a syntax tree from a FROM expression.
7366
7367    Example:
7368        >>> from_("tbl").select("col1", "col2").sql()
7369        'SELECT col1, col2 FROM tbl'
7370
7371    Args:
7372        *expression: the SQL code string to parse as the FROM expressions of a
7373            SELECT statement. If an Expression instance is passed, this is used as-is.
7374        dialect: the dialect used to parse the input expression (in the case that the
7375            input expression is a SQL string).
7376        **opts: other options to use to parse the input expressions (again, in the case
7377            that the input expression is a SQL string).
7378
7379    Returns:
7380        Select: the syntax tree for the SELECT statement.
7381    """
7382    return Select().from_(expression, dialect=dialect, **opts)

Initializes a syntax tree from a FROM expression.

Example:
>>> from_("tbl").select("col1", "col2").sql()
'SELECT col1, col2 FROM tbl'
Arguments:
  • *expression: the SQL code string to parse as the FROM expressions of a SELECT statement. If an Expression instance is passed, this is used as-is.
  • dialect: the dialect used to parse the input expression (in the case that the input expression is a SQL string).
  • **opts: other options to use to parse the input expressions (again, in the case that the input expression is a SQL string).
Returns:

Select: the syntax tree for the SELECT statement.

def update( table: str | Table, properties: Optional[dict] = None, where: Union[str, Expression, NoneType] = None, from_: Union[str, Expression, NoneType] = None, with_: Optional[Dict[str, Union[str, Expression]]] = None, dialect: Union[str, sqlglot.dialects.Dialect, Type[sqlglot.dialects.Dialect], NoneType] = None, **opts) -> Update:
7385def update(
7386    table: str | Table,
7387    properties: t.Optional[dict] = None,
7388    where: t.Optional[ExpOrStr] = None,
7389    from_: t.Optional[ExpOrStr] = None,
7390    with_: t.Optional[t.Dict[str, ExpOrStr]] = None,
7391    dialect: DialectType = None,
7392    **opts,
7393) -> Update:
7394    """
7395    Creates an update statement.
7396
7397    Example:
7398        >>> update("my_table", {"x": 1, "y": "2", "z": None}, from_="baz_cte", where="baz_cte.id > 1 and my_table.id = baz_cte.id", with_={"baz_cte": "SELECT id FROM foo"}).sql()
7399        "WITH baz_cte AS (SELECT id FROM foo) UPDATE my_table SET x = 1, y = '2', z = NULL FROM baz_cte WHERE baz_cte.id > 1 AND my_table.id = baz_cte.id"
7400
7401    Args:
7402        properties: dictionary of properties to SET which are
7403            auto converted to sql objects eg None -> NULL
7404        where: sql conditional parsed into a WHERE statement
7405        from_: sql statement parsed into a FROM statement
7406        with_: dictionary of CTE aliases / select statements to include in a WITH clause.
7407        dialect: the dialect used to parse the input expressions.
7408        **opts: other options to use to parse the input expressions.
7409
7410    Returns:
7411        Update: the syntax tree for the UPDATE statement.
7412    """
7413    update_expr = Update(this=maybe_parse(table, into=Table, dialect=dialect))
7414    if properties:
7415        update_expr.set(
7416            "expressions",
7417            [
7418                EQ(this=maybe_parse(k, dialect=dialect, **opts), expression=convert(v))
7419                for k, v in properties.items()
7420            ],
7421        )
7422    if from_:
7423        update_expr.set(
7424            "from",
7425            maybe_parse(from_, into=From, dialect=dialect, prefix="FROM", **opts),
7426        )
7427    if isinstance(where, Condition):
7428        where = Where(this=where)
7429    if where:
7430        update_expr.set(
7431            "where",
7432            maybe_parse(where, into=Where, dialect=dialect, prefix="WHERE", **opts),
7433        )
7434    if with_:
7435        cte_list = [
7436            alias_(CTE(this=maybe_parse(qry, dialect=dialect, **opts)), alias, table=True)
7437            for alias, qry in with_.items()
7438        ]
7439        update_expr.set(
7440            "with",
7441            With(expressions=cte_list),
7442        )
7443    return update_expr

Creates an update statement.

Example:
>>> update("my_table", {"x": 1, "y": "2", "z": None}, from_="baz_cte", where="baz_cte.id > 1 and my_table.id = baz_cte.id", with_={"baz_cte": "SELECT id FROM foo"}).sql()
"WITH baz_cte AS (SELECT id FROM foo) UPDATE my_table SET x = 1, y = '2', z = NULL FROM baz_cte WHERE baz_cte.id > 1 AND my_table.id = baz_cte.id"
Arguments:
  • properties: dictionary of properties to SET which are auto converted to sql objects eg None -> NULL
  • where: sql conditional parsed into a WHERE statement
  • from_: sql statement parsed into a FROM statement
  • with_: dictionary of CTE aliases / select statements to include in a WITH clause.
  • dialect: the dialect used to parse the input expressions.
  • **opts: other options to use to parse the input expressions.
Returns:

Update: the syntax tree for the UPDATE statement.

def delete( table: Union[str, Expression], where: Union[str, Expression, NoneType] = None, returning: Union[str, Expression, NoneType] = None, dialect: Union[str, sqlglot.dialects.Dialect, Type[sqlglot.dialects.Dialect], NoneType] = None, **opts) -> Delete:
7446def delete(
7447    table: ExpOrStr,
7448    where: t.Optional[ExpOrStr] = None,
7449    returning: t.Optional[ExpOrStr] = None,
7450    dialect: DialectType = None,
7451    **opts,
7452) -> Delete:
7453    """
7454    Builds a delete statement.
7455
7456    Example:
7457        >>> delete("my_table", where="id > 1").sql()
7458        'DELETE FROM my_table WHERE id > 1'
7459
7460    Args:
7461        where: sql conditional parsed into a WHERE statement
7462        returning: sql conditional parsed into a RETURNING statement
7463        dialect: the dialect used to parse the input expressions.
7464        **opts: other options to use to parse the input expressions.
7465
7466    Returns:
7467        Delete: the syntax tree for the DELETE statement.
7468    """
7469    delete_expr = Delete().delete(table, dialect=dialect, copy=False, **opts)
7470    if where:
7471        delete_expr = delete_expr.where(where, dialect=dialect, copy=False, **opts)
7472    if returning:
7473        delete_expr = delete_expr.returning(returning, dialect=dialect, copy=False, **opts)
7474    return delete_expr

Builds a delete statement.

Example:
>>> delete("my_table", where="id > 1").sql()
'DELETE FROM my_table WHERE id > 1'
Arguments:
  • where: sql conditional parsed into a WHERE statement
  • returning: sql conditional parsed into a RETURNING statement
  • dialect: the dialect used to parse the input expressions.
  • **opts: other options to use to parse the input expressions.
Returns:

Delete: the syntax tree for the DELETE statement.

def insert( expression: Union[str, Expression], into: Union[str, Expression], columns: Optional[Sequence[str | Identifier]] = None, overwrite: Optional[bool] = None, returning: Union[str, Expression, NoneType] = None, dialect: Union[str, sqlglot.dialects.Dialect, Type[sqlglot.dialects.Dialect], NoneType] = None, copy: bool = True, **opts) -> Insert:
7477def insert(
7478    expression: ExpOrStr,
7479    into: ExpOrStr,
7480    columns: t.Optional[t.Sequence[str | Identifier]] = None,
7481    overwrite: t.Optional[bool] = None,
7482    returning: t.Optional[ExpOrStr] = None,
7483    dialect: DialectType = None,
7484    copy: bool = True,
7485    **opts,
7486) -> Insert:
7487    """
7488    Builds an INSERT statement.
7489
7490    Example:
7491        >>> insert("VALUES (1, 2, 3)", "tbl").sql()
7492        'INSERT INTO tbl VALUES (1, 2, 3)'
7493
7494    Args:
7495        expression: the sql string or expression of the INSERT statement
7496        into: the tbl to insert data to.
7497        columns: optionally the table's column names.
7498        overwrite: whether to INSERT OVERWRITE or not.
7499        returning: sql conditional parsed into a RETURNING statement
7500        dialect: the dialect used to parse the input expressions.
7501        copy: whether to copy the expression.
7502        **opts: other options to use to parse the input expressions.
7503
7504    Returns:
7505        Insert: the syntax tree for the INSERT statement.
7506    """
7507    expr = maybe_parse(expression, dialect=dialect, copy=copy, **opts)
7508    this: Table | Schema = maybe_parse(into, into=Table, dialect=dialect, copy=copy, **opts)
7509
7510    if columns:
7511        this = Schema(this=this, expressions=[to_identifier(c, copy=copy) for c in columns])
7512
7513    insert = Insert(this=this, expression=expr, overwrite=overwrite)
7514
7515    if returning:
7516        insert = insert.returning(returning, dialect=dialect, copy=False, **opts)
7517
7518    return insert

Builds an INSERT statement.

Example:
>>> insert("VALUES (1, 2, 3)", "tbl").sql()
'INSERT INTO tbl VALUES (1, 2, 3)'
Arguments:
  • expression: the sql string or expression of the INSERT statement
  • into: the tbl to insert data to.
  • columns: optionally the table's column names.
  • overwrite: whether to INSERT OVERWRITE or not.
  • returning: sql conditional parsed into a RETURNING statement
  • dialect: the dialect used to parse the input expressions.
  • copy: whether to copy the expression.
  • **opts: other options to use to parse the input expressions.
Returns:

Insert: the syntax tree for the INSERT statement.

def merge( *when_exprs: Union[str, Expression], into: Union[str, Expression], using: Union[str, Expression], on: Union[str, Expression], returning: Union[str, Expression, NoneType] = None, dialect: Union[str, sqlglot.dialects.Dialect, Type[sqlglot.dialects.Dialect], NoneType] = None, copy: bool = True, **opts) -> Merge:
7521def merge(
7522    *when_exprs: ExpOrStr,
7523    into: ExpOrStr,
7524    using: ExpOrStr,
7525    on: ExpOrStr,
7526    returning: t.Optional[ExpOrStr] = None,
7527    dialect: DialectType = None,
7528    copy: bool = True,
7529    **opts,
7530) -> Merge:
7531    """
7532    Builds a MERGE statement.
7533
7534    Example:
7535        >>> merge("WHEN MATCHED THEN UPDATE SET col1 = source_table.col1",
7536        ...       "WHEN NOT MATCHED THEN INSERT (col1) VALUES (source_table.col1)",
7537        ...       into="my_table",
7538        ...       using="source_table",
7539        ...       on="my_table.id = source_table.id").sql()
7540        'MERGE INTO my_table USING source_table ON my_table.id = source_table.id WHEN MATCHED THEN UPDATE SET col1 = source_table.col1 WHEN NOT MATCHED THEN INSERT (col1) VALUES (source_table.col1)'
7541
7542    Args:
7543        *when_exprs: The WHEN clauses specifying actions for matched and unmatched rows.
7544        into: The target table to merge data into.
7545        using: The source table to merge data from.
7546        on: The join condition for the merge.
7547        returning: The columns to return from the merge.
7548        dialect: The dialect used to parse the input expressions.
7549        copy: Whether to copy the expression.
7550        **opts: Other options to use to parse the input expressions.
7551
7552    Returns:
7553        Merge: The syntax tree for the MERGE statement.
7554    """
7555    expressions: t.List[Expression] = []
7556    for when_expr in when_exprs:
7557        expression = maybe_parse(when_expr, dialect=dialect, copy=copy, into=Whens, **opts)
7558        expressions.extend([expression] if isinstance(expression, When) else expression.expressions)
7559
7560    merge = Merge(
7561        this=maybe_parse(into, dialect=dialect, copy=copy, **opts),
7562        using=maybe_parse(using, dialect=dialect, copy=copy, **opts),
7563        on=maybe_parse(on, dialect=dialect, copy=copy, **opts),
7564        whens=Whens(expressions=expressions),
7565    )
7566    if returning:
7567        merge = merge.returning(returning, dialect=dialect, copy=False, **opts)
7568
7569    return merge

Builds a MERGE statement.

Example:
>>> merge("WHEN MATCHED THEN UPDATE SET col1 = source_table.col1",
...       "WHEN NOT MATCHED THEN INSERT (col1) VALUES (source_table.col1)",
...       into="my_table",
...       using="source_table",
...       on="my_table.id = source_table.id").sql()
'MERGE INTO my_table USING source_table ON my_table.id = source_table.id WHEN MATCHED THEN UPDATE SET col1 = source_table.col1 WHEN NOT MATCHED THEN INSERT (col1) VALUES (source_table.col1)'
Arguments:
  • *when_exprs: The WHEN clauses specifying actions for matched and unmatched rows.
  • into: The target table to merge data into.
  • using: The source table to merge data from.
  • on: The join condition for the merge.
  • returning: The columns to return from the merge.
  • dialect: The dialect used to parse the input expressions.
  • copy: Whether to copy the expression.
  • **opts: Other options to use to parse the input expressions.
Returns:

Merge: The syntax tree for the MERGE statement.

def condition( expression: Union[str, Expression], dialect: Union[str, sqlglot.dialects.Dialect, Type[sqlglot.dialects.Dialect], NoneType] = None, copy: bool = True, **opts) -> Condition:
7572def condition(
7573    expression: ExpOrStr, dialect: DialectType = None, copy: bool = True, **opts
7574) -> Condition:
7575    """
7576    Initialize a logical condition expression.
7577
7578    Example:
7579        >>> condition("x=1").sql()
7580        'x = 1'
7581
7582        This is helpful for composing larger logical syntax trees:
7583        >>> where = condition("x=1")
7584        >>> where = where.and_("y=1")
7585        >>> Select().from_("tbl").select("*").where(where).sql()
7586        'SELECT * FROM tbl WHERE x = 1 AND y = 1'
7587
7588    Args:
7589        *expression: the SQL code string to parse.
7590            If an Expression instance is passed, this is used as-is.
7591        dialect: the dialect used to parse the input expression (in the case that the
7592            input expression is a SQL string).
7593        copy: Whether to copy `expression` (only applies to expressions).
7594        **opts: other options to use to parse the input expressions (again, in the case
7595            that the input expression is a SQL string).
7596
7597    Returns:
7598        The new Condition instance
7599    """
7600    return maybe_parse(
7601        expression,
7602        into=Condition,
7603        dialect=dialect,
7604        copy=copy,
7605        **opts,
7606    )

Initialize a logical condition expression.

Example:
>>> condition("x=1").sql()
'x = 1'

This is helpful for composing larger logical syntax trees:

>>> where = condition("x=1")
>>> where = where.and_("y=1")
>>> Select().from_("tbl").select("*").where(where).sql()
'SELECT * FROM tbl WHERE x = 1 AND y = 1'
Arguments:
  • *expression: the SQL code string to parse. If an Expression instance is passed, this is used as-is.
  • dialect: the dialect used to parse the input expression (in the case that the input expression is a SQL string).
  • copy: Whether to copy expression (only applies to expressions).
  • **opts: other options to use to parse the input expressions (again, in the case that the input expression is a SQL string).
Returns:

The new Condition instance

def and_( *expressions: Union[str, Expression, NoneType], dialect: Union[str, sqlglot.dialects.Dialect, Type[sqlglot.dialects.Dialect], NoneType] = None, copy: bool = True, wrap: bool = True, **opts) -> Condition:
7609def and_(
7610    *expressions: t.Optional[ExpOrStr],
7611    dialect: DialectType = None,
7612    copy: bool = True,
7613    wrap: bool = True,
7614    **opts,
7615) -> Condition:
7616    """
7617    Combine multiple conditions with an AND logical operator.
7618
7619    Example:
7620        >>> and_("x=1", and_("y=1", "z=1")).sql()
7621        'x = 1 AND (y = 1 AND z = 1)'
7622
7623    Args:
7624        *expressions: the SQL code strings to parse.
7625            If an Expression instance is passed, this is used as-is.
7626        dialect: the dialect used to parse the input expression.
7627        copy: whether to copy `expressions` (only applies to Expressions).
7628        wrap: whether to wrap the operands in `Paren`s. This is true by default to avoid
7629            precedence issues, but can be turned off when the produced AST is too deep and
7630            causes recursion-related issues.
7631        **opts: other options to use to parse the input expressions.
7632
7633    Returns:
7634        The new condition
7635    """
7636    return t.cast(Condition, _combine(expressions, And, dialect, copy=copy, wrap=wrap, **opts))

Combine multiple conditions with an AND logical operator.

Example:
>>> and_("x=1", and_("y=1", "z=1")).sql()
'x = 1 AND (y = 1 AND z = 1)'
Arguments:
  • *expressions: the SQL code strings to parse. If an Expression instance is passed, this is used as-is.
  • dialect: the dialect used to parse the input expression.
  • copy: whether to copy expressions (only applies to Expressions).
  • wrap: whether to wrap the operands in Parens. This is true by default to avoid precedence issues, but can be turned off when the produced AST is too deep and causes recursion-related issues.
  • **opts: other options to use to parse the input expressions.
Returns:

The new condition

def or_( *expressions: Union[str, Expression, NoneType], dialect: Union[str, sqlglot.dialects.Dialect, Type[sqlglot.dialects.Dialect], NoneType] = None, copy: bool = True, wrap: bool = True, **opts) -> Condition:
7639def or_(
7640    *expressions: t.Optional[ExpOrStr],
7641    dialect: DialectType = None,
7642    copy: bool = True,
7643    wrap: bool = True,
7644    **opts,
7645) -> Condition:
7646    """
7647    Combine multiple conditions with an OR logical operator.
7648
7649    Example:
7650        >>> or_("x=1", or_("y=1", "z=1")).sql()
7651        'x = 1 OR (y = 1 OR z = 1)'
7652
7653    Args:
7654        *expressions: the SQL code strings to parse.
7655            If an Expression instance is passed, this is used as-is.
7656        dialect: the dialect used to parse the input expression.
7657        copy: whether to copy `expressions` (only applies to Expressions).
7658        wrap: whether to wrap the operands in `Paren`s. This is true by default to avoid
7659            precedence issues, but can be turned off when the produced AST is too deep and
7660            causes recursion-related issues.
7661        **opts: other options to use to parse the input expressions.
7662
7663    Returns:
7664        The new condition
7665    """
7666    return t.cast(Condition, _combine(expressions, Or, dialect, copy=copy, wrap=wrap, **opts))

Combine multiple conditions with an OR logical operator.

Example:
>>> or_("x=1", or_("y=1", "z=1")).sql()
'x = 1 OR (y = 1 OR z = 1)'
Arguments:
  • *expressions: the SQL code strings to parse. If an Expression instance is passed, this is used as-is.
  • dialect: the dialect used to parse the input expression.
  • copy: whether to copy expressions (only applies to Expressions).
  • wrap: whether to wrap the operands in Parens. This is true by default to avoid precedence issues, but can be turned off when the produced AST is too deep and causes recursion-related issues.
  • **opts: other options to use to parse the input expressions.
Returns:

The new condition

def xor( *expressions: Union[str, Expression, NoneType], dialect: Union[str, sqlglot.dialects.Dialect, Type[sqlglot.dialects.Dialect], NoneType] = None, copy: bool = True, wrap: bool = True, **opts) -> Condition:
7669def xor(
7670    *expressions: t.Optional[ExpOrStr],
7671    dialect: DialectType = None,
7672    copy: bool = True,
7673    wrap: bool = True,
7674    **opts,
7675) -> Condition:
7676    """
7677    Combine multiple conditions with an XOR logical operator.
7678
7679    Example:
7680        >>> xor("x=1", xor("y=1", "z=1")).sql()
7681        'x = 1 XOR (y = 1 XOR z = 1)'
7682
7683    Args:
7684        *expressions: the SQL code strings to parse.
7685            If an Expression instance is passed, this is used as-is.
7686        dialect: the dialect used to parse the input expression.
7687        copy: whether to copy `expressions` (only applies to Expressions).
7688        wrap: whether to wrap the operands in `Paren`s. This is true by default to avoid
7689            precedence issues, but can be turned off when the produced AST is too deep and
7690            causes recursion-related issues.
7691        **opts: other options to use to parse the input expressions.
7692
7693    Returns:
7694        The new condition
7695    """
7696    return t.cast(Condition, _combine(expressions, Xor, dialect, copy=copy, wrap=wrap, **opts))

Combine multiple conditions with an XOR logical operator.

Example:
>>> xor("x=1", xor("y=1", "z=1")).sql()
'x = 1 XOR (y = 1 XOR z = 1)'
Arguments:
  • *expressions: the SQL code strings to parse. If an Expression instance is passed, this is used as-is.
  • dialect: the dialect used to parse the input expression.
  • copy: whether to copy expressions (only applies to Expressions).
  • wrap: whether to wrap the operands in Parens. This is true by default to avoid precedence issues, but can be turned off when the produced AST is too deep and causes recursion-related issues.
  • **opts: other options to use to parse the input expressions.
Returns:

The new condition

def not_( expression: Union[str, Expression], dialect: Union[str, sqlglot.dialects.Dialect, Type[sqlglot.dialects.Dialect], NoneType] = None, copy: bool = True, **opts) -> Not:
7699def not_(expression: ExpOrStr, dialect: DialectType = None, copy: bool = True, **opts) -> Not:
7700    """
7701    Wrap a condition with a NOT operator.
7702
7703    Example:
7704        >>> not_("this_suit='black'").sql()
7705        "NOT this_suit = 'black'"
7706
7707    Args:
7708        expression: the SQL code string to parse.
7709            If an Expression instance is passed, this is used as-is.
7710        dialect: the dialect used to parse the input expression.
7711        copy: whether to copy the expression or not.
7712        **opts: other options to use to parse the input expressions.
7713
7714    Returns:
7715        The new condition.
7716    """
7717    this = condition(
7718        expression,
7719        dialect=dialect,
7720        copy=copy,
7721        **opts,
7722    )
7723    return Not(this=_wrap(this, Connector))

Wrap a condition with a NOT operator.

Example:
>>> not_("this_suit='black'").sql()
"NOT this_suit = 'black'"
Arguments:
  • expression: the SQL code string to parse. If an Expression instance is passed, this is used as-is.
  • dialect: the dialect used to parse the input expression.
  • copy: whether to copy the expression or not.
  • **opts: other options to use to parse the input expressions.
Returns:

The new condition.

def paren( expression: Union[str, Expression], copy: bool = True) -> Paren:
7726def paren(expression: ExpOrStr, copy: bool = True) -> Paren:
7727    """
7728    Wrap an expression in parentheses.
7729
7730    Example:
7731        >>> paren("5 + 3").sql()
7732        '(5 + 3)'
7733
7734    Args:
7735        expression: the SQL code string to parse.
7736            If an Expression instance is passed, this is used as-is.
7737        copy: whether to copy the expression or not.
7738
7739    Returns:
7740        The wrapped expression.
7741    """
7742    return Paren(this=maybe_parse(expression, copy=copy))

Wrap an expression in parentheses.

Example:
>>> paren("5 + 3").sql()
'(5 + 3)'
Arguments:
  • expression: the SQL code string to parse. If an Expression instance is passed, this is used as-is.
  • copy: whether to copy the expression or not.
Returns:

The wrapped expression.

SAFE_IDENTIFIER_RE: Pattern[str] = re.compile('^[_a-zA-Z][\\w]*$')
def to_identifier(name, quoted=None, copy=True):
7758def to_identifier(name, quoted=None, copy=True):
7759    """Builds an identifier.
7760
7761    Args:
7762        name: The name to turn into an identifier.
7763        quoted: Whether to force quote the identifier.
7764        copy: Whether to copy name if it's an Identifier.
7765
7766    Returns:
7767        The identifier ast node.
7768    """
7769
7770    if name is None:
7771        return None
7772
7773    if isinstance(name, Identifier):
7774        identifier = maybe_copy(name, copy)
7775    elif isinstance(name, str):
7776        identifier = Identifier(
7777            this=name,
7778            quoted=not SAFE_IDENTIFIER_RE.match(name) if quoted is None else quoted,
7779        )
7780    else:
7781        raise ValueError(f"Name needs to be a string or an Identifier, got: {name.__class__}")
7782    return identifier

Builds an identifier.

Arguments:
  • name: The name to turn into an identifier.
  • quoted: Whether to force quote the identifier.
  • copy: Whether to copy name if it's an Identifier.
Returns:

The identifier ast node.

def parse_identifier( name: str | Identifier, dialect: Union[str, sqlglot.dialects.Dialect, Type[sqlglot.dialects.Dialect], NoneType] = None) -> Identifier:
7785def parse_identifier(name: str | Identifier, dialect: DialectType = None) -> Identifier:
7786    """
7787    Parses a given string into an identifier.
7788
7789    Args:
7790        name: The name to parse into an identifier.
7791        dialect: The dialect to parse against.
7792
7793    Returns:
7794        The identifier ast node.
7795    """
7796    try:
7797        expression = maybe_parse(name, dialect=dialect, into=Identifier)
7798    except (ParseError, TokenError):
7799        expression = to_identifier(name)
7800
7801    return expression

Parses a given string into an identifier.

Arguments:
  • name: The name to parse into an identifier.
  • dialect: The dialect to parse against.
Returns:

The identifier ast node.

INTERVAL_STRING_RE = re.compile('\\s*([0-9]+)\\s*([a-zA-Z]+)\\s*')
def to_interval( interval: str | Literal) -> Interval:
7807def to_interval(interval: str | Literal) -> Interval:
7808    """Builds an interval expression from a string like '1 day' or '5 months'."""
7809    if isinstance(interval, Literal):
7810        if not interval.is_string:
7811            raise ValueError("Invalid interval string.")
7812
7813        interval = interval.this
7814
7815    interval = maybe_parse(f"INTERVAL {interval}")
7816    assert isinstance(interval, Interval)
7817    return interval

Builds an interval expression from a string like '1 day' or '5 months'.

def to_table( sql_path: str | Table, dialect: Union[str, sqlglot.dialects.Dialect, Type[sqlglot.dialects.Dialect], NoneType] = None, copy: bool = True, **kwargs) -> Table:
7820def to_table(
7821    sql_path: str | Table, dialect: DialectType = None, copy: bool = True, **kwargs
7822) -> Table:
7823    """
7824    Create a table expression from a `[catalog].[schema].[table]` sql path. Catalog and schema are optional.
7825    If a table is passed in then that table is returned.
7826
7827    Args:
7828        sql_path: a `[catalog].[schema].[table]` string.
7829        dialect: the source dialect according to which the table name will be parsed.
7830        copy: Whether to copy a table if it is passed in.
7831        kwargs: the kwargs to instantiate the resulting `Table` expression with.
7832
7833    Returns:
7834        A table expression.
7835    """
7836    if isinstance(sql_path, Table):
7837        return maybe_copy(sql_path, copy=copy)
7838
7839    table = maybe_parse(sql_path, into=Table, dialect=dialect)
7840
7841    for k, v in kwargs.items():
7842        table.set(k, v)
7843
7844    return table

Create a table expression from a [catalog].[schema].[table] sql path. Catalog and schema are optional. If a table is passed in then that table is returned.

Arguments:
  • sql_path: a [catalog].[schema].[table] string.
  • dialect: the source dialect according to which the table name will be parsed.
  • copy: Whether to copy a table if it is passed in.
  • kwargs: the kwargs to instantiate the resulting Table expression with.
Returns:

A table expression.

def to_column( sql_path: str | Column, quoted: Optional[bool] = None, dialect: Union[str, sqlglot.dialects.Dialect, Type[sqlglot.dialects.Dialect], NoneType] = None, copy: bool = True, **kwargs) -> Column:
7847def to_column(
7848    sql_path: str | Column,
7849    quoted: t.Optional[bool] = None,
7850    dialect: DialectType = None,
7851    copy: bool = True,
7852    **kwargs,
7853) -> Column:
7854    """
7855    Create a column from a `[table].[column]` sql path. Table is optional.
7856    If a column is passed in then that column is returned.
7857
7858    Args:
7859        sql_path: a `[table].[column]` string.
7860        quoted: Whether or not to force quote identifiers.
7861        dialect: the source dialect according to which the column name will be parsed.
7862        copy: Whether to copy a column if it is passed in.
7863        kwargs: the kwargs to instantiate the resulting `Column` expression with.
7864
7865    Returns:
7866        A column expression.
7867    """
7868    if isinstance(sql_path, Column):
7869        return maybe_copy(sql_path, copy=copy)
7870
7871    try:
7872        col = maybe_parse(sql_path, into=Column, dialect=dialect)
7873    except ParseError:
7874        return column(*reversed(sql_path.split(".")), quoted=quoted, **kwargs)
7875
7876    for k, v in kwargs.items():
7877        col.set(k, v)
7878
7879    if quoted:
7880        for i in col.find_all(Identifier):
7881            i.set("quoted", True)
7882
7883    return col

Create a column from a [table].[column] sql path. Table is optional. If a column is passed in then that column is returned.

Arguments:
  • sql_path: a [table].[column] string.
  • quoted: Whether or not to force quote identifiers.
  • dialect: the source dialect according to which the column name will be parsed.
  • copy: Whether to copy a column if it is passed in.
  • kwargs: the kwargs to instantiate the resulting Column expression with.
Returns:

A column expression.

def alias_( expression: Union[str, Expression], alias: Union[Identifier, str, NoneType], table: Union[bool, Sequence[str | Identifier]] = False, quoted: Optional[bool] = None, dialect: Union[str, sqlglot.dialects.Dialect, Type[sqlglot.dialects.Dialect], NoneType] = None, copy: bool = True, **opts):
7886def alias_(
7887    expression: ExpOrStr,
7888    alias: t.Optional[str | Identifier],
7889    table: bool | t.Sequence[str | Identifier] = False,
7890    quoted: t.Optional[bool] = None,
7891    dialect: DialectType = None,
7892    copy: bool = True,
7893    **opts,
7894):
7895    """Create an Alias expression.
7896
7897    Example:
7898        >>> alias_('foo', 'bar').sql()
7899        'foo AS bar'
7900
7901        >>> alias_('(select 1, 2)', 'bar', table=['a', 'b']).sql()
7902        '(SELECT 1, 2) AS bar(a, b)'
7903
7904    Args:
7905        expression: the SQL code strings to parse.
7906            If an Expression instance is passed, this is used as-is.
7907        alias: the alias name to use. If the name has
7908            special characters it is quoted.
7909        table: Whether to create a table alias, can also be a list of columns.
7910        quoted: whether to quote the alias
7911        dialect: the dialect used to parse the input expression.
7912        copy: Whether to copy the expression.
7913        **opts: other options to use to parse the input expressions.
7914
7915    Returns:
7916        Alias: the aliased expression
7917    """
7918    exp = maybe_parse(expression, dialect=dialect, copy=copy, **opts)
7919    alias = to_identifier(alias, quoted=quoted)
7920
7921    if table:
7922        table_alias = TableAlias(this=alias)
7923        exp.set("alias", table_alias)
7924
7925        if not isinstance(table, bool):
7926            for column in table:
7927                table_alias.append("columns", to_identifier(column, quoted=quoted))
7928
7929        return exp
7930
7931    # We don't set the "alias" arg for Window expressions, because that would add an IDENTIFIER node in
7932    # the AST, representing a "named_window" [1] construct (eg. bigquery). What we want is an ALIAS node
7933    # for the complete Window expression.
7934    #
7935    # [1]: https://cloud.google.com/bigquery/docs/reference/standard-sql/window-function-calls
7936
7937    if "alias" in exp.arg_types and not isinstance(exp, Window):
7938        exp.set("alias", alias)
7939        return exp
7940    return Alias(this=exp, alias=alias)

Create an Alias expression.

Example:
>>> alias_('foo', 'bar').sql()
'foo AS bar'
>>> alias_('(select 1, 2)', 'bar', table=['a', 'b']).sql()
'(SELECT 1, 2) AS bar(a, b)'
Arguments:
  • expression: the SQL code strings to parse. If an Expression instance is passed, this is used as-is.
  • alias: the alias name to use. If the name has special characters it is quoted.
  • table: Whether to create a table alias, can also be a list of columns.
  • quoted: whether to quote the alias
  • dialect: the dialect used to parse the input expression.
  • copy: Whether to copy the expression.
  • **opts: other options to use to parse the input expressions.
Returns:

Alias: the aliased expression

def subquery( expression: Union[str, Expression], alias: Union[Identifier, str, NoneType] = None, dialect: Union[str, sqlglot.dialects.Dialect, Type[sqlglot.dialects.Dialect], NoneType] = None, **opts) -> Select:
7943def subquery(
7944    expression: ExpOrStr,
7945    alias: t.Optional[Identifier | str] = None,
7946    dialect: DialectType = None,
7947    **opts,
7948) -> Select:
7949    """
7950    Build a subquery expression that's selected from.
7951
7952    Example:
7953        >>> subquery('select x from tbl', 'bar').select('x').sql()
7954        'SELECT x FROM (SELECT x FROM tbl) AS bar'
7955
7956    Args:
7957        expression: the SQL code strings to parse.
7958            If an Expression instance is passed, this is used as-is.
7959        alias: the alias name to use.
7960        dialect: the dialect used to parse the input expression.
7961        **opts: other options to use to parse the input expressions.
7962
7963    Returns:
7964        A new Select instance with the subquery expression included.
7965    """
7966
7967    expression = maybe_parse(expression, dialect=dialect, **opts).subquery(alias, **opts)
7968    return Select().from_(expression, dialect=dialect, **opts)

Build a subquery expression that's selected from.

Example:
>>> subquery('select x from tbl', 'bar').select('x').sql()
'SELECT x FROM (SELECT x FROM tbl) AS bar'
Arguments:
  • expression: the SQL code strings to parse. If an Expression instance is passed, this is used as-is.
  • alias: the alias name to use.
  • dialect: the dialect used to parse the input expression.
  • **opts: other options to use to parse the input expressions.
Returns:

A new Select instance with the subquery expression included.

def column( col, table=None, db=None, catalog=None, *, fields=None, quoted=None, copy=True):
7999def column(
8000    col,
8001    table=None,
8002    db=None,
8003    catalog=None,
8004    *,
8005    fields=None,
8006    quoted=None,
8007    copy=True,
8008):
8009    """
8010    Build a Column.
8011
8012    Args:
8013        col: Column name.
8014        table: Table name.
8015        db: Database name.
8016        catalog: Catalog name.
8017        fields: Additional fields using dots.
8018        quoted: Whether to force quotes on the column's identifiers.
8019        copy: Whether to copy identifiers if passed in.
8020
8021    Returns:
8022        The new Column instance.
8023    """
8024    this = Column(
8025        this=to_identifier(col, quoted=quoted, copy=copy),
8026        table=to_identifier(table, quoted=quoted, copy=copy),
8027        db=to_identifier(db, quoted=quoted, copy=copy),
8028        catalog=to_identifier(catalog, quoted=quoted, copy=copy),
8029    )
8030
8031    if fields:
8032        this = Dot.build(
8033            (this, *(to_identifier(field, quoted=quoted, copy=copy) for field in fields))
8034        )
8035    return this

Build a Column.

Arguments:
  • col: Column name.
  • table: Table name.
  • db: Database name.
  • catalog: Catalog name.
  • fields: Additional fields using dots.
  • quoted: Whether to force quotes on the column's identifiers.
  • copy: Whether to copy identifiers if passed in.
Returns:

The new Column instance.

def cast( expression: Union[str, Expression], to: Union[str, DataType, DataType.Type], copy: bool = True, dialect: Union[str, sqlglot.dialects.Dialect, Type[sqlglot.dialects.Dialect], NoneType] = None, **opts) -> Cast:
8038def cast(
8039    expression: ExpOrStr, to: DATA_TYPE, copy: bool = True, dialect: DialectType = None, **opts
8040) -> Cast:
8041    """Cast an expression to a data type.
8042
8043    Example:
8044        >>> cast('x + 1', 'int').sql()
8045        'CAST(x + 1 AS INT)'
8046
8047    Args:
8048        expression: The expression to cast.
8049        to: The datatype to cast to.
8050        copy: Whether to copy the supplied expressions.
8051        dialect: The target dialect. This is used to prevent a re-cast in the following scenario:
8052            - The expression to be cast is already a exp.Cast expression
8053            - The existing cast is to a type that is logically equivalent to new type
8054
8055            For example, if :expression='CAST(x as DATETIME)' and :to=Type.TIMESTAMP,
8056            but in the target dialect DATETIME is mapped to TIMESTAMP, then we will NOT return `CAST(x (as DATETIME) as TIMESTAMP)`
8057            and instead just return the original expression `CAST(x as DATETIME)`.
8058
8059            This is to prevent it being output as a double cast `CAST(x (as TIMESTAMP) as TIMESTAMP)` once the DATETIME -> TIMESTAMP
8060            mapping is applied in the target dialect generator.
8061
8062    Returns:
8063        The new Cast instance.
8064    """
8065    expr = maybe_parse(expression, copy=copy, dialect=dialect, **opts)
8066    data_type = DataType.build(to, copy=copy, dialect=dialect, **opts)
8067
8068    # dont re-cast if the expression is already a cast to the correct type
8069    if isinstance(expr, Cast):
8070        from sqlglot.dialects.dialect import Dialect
8071
8072        target_dialect = Dialect.get_or_raise(dialect)
8073        type_mapping = target_dialect.generator_class.TYPE_MAPPING
8074
8075        existing_cast_type: DataType.Type = expr.to.this
8076        new_cast_type: DataType.Type = data_type.this
8077        types_are_equivalent = type_mapping.get(
8078            existing_cast_type, existing_cast_type.value
8079        ) == type_mapping.get(new_cast_type, new_cast_type.value)
8080
8081        if expr.is_type(data_type) or types_are_equivalent:
8082            return expr
8083
8084    expr = Cast(this=expr, to=data_type)
8085    expr.type = data_type
8086
8087    return expr

Cast an expression to a data type.

Example:
>>> cast('x + 1', 'int').sql()
'CAST(x + 1 AS INT)'
Arguments:
  • expression: The expression to cast.
  • to: The datatype to cast to.
  • copy: Whether to copy the supplied expressions.
  • dialect: The target dialect. This is used to prevent a re-cast in the following scenario:

    • The expression to be cast is already a exp.Cast expression
    • The existing cast is to a type that is logically equivalent to new type

    For example, if :expression='CAST(x as DATETIME)' and :to=Type.TIMESTAMP, but in the target dialect DATETIME is mapped to TIMESTAMP, then we will NOT return CAST(x (as DATETIME) as TIMESTAMP) and instead just return the original expression CAST(x as DATETIME).

    This is to prevent it being output as a double cast CAST(x (as TIMESTAMP) as TIMESTAMP) once the DATETIME -> TIMESTAMP mapping is applied in the target dialect generator.

Returns:

The new Cast instance.

def table_( table: Identifier | str, db: Union[Identifier, str, NoneType] = None, catalog: Union[Identifier, str, NoneType] = None, quoted: Optional[bool] = None, alias: Union[Identifier, str, NoneType] = None) -> Table:
8090def table_(
8091    table: Identifier | str,
8092    db: t.Optional[Identifier | str] = None,
8093    catalog: t.Optional[Identifier | str] = None,
8094    quoted: t.Optional[bool] = None,
8095    alias: t.Optional[Identifier | str] = None,
8096) -> Table:
8097    """Build a Table.
8098
8099    Args:
8100        table: Table name.
8101        db: Database name.
8102        catalog: Catalog name.
8103        quote: Whether to force quotes on the table's identifiers.
8104        alias: Table's alias.
8105
8106    Returns:
8107        The new Table instance.
8108    """
8109    return Table(
8110        this=to_identifier(table, quoted=quoted) if table else None,
8111        db=to_identifier(db, quoted=quoted) if db else None,
8112        catalog=to_identifier(catalog, quoted=quoted) if catalog else None,
8113        alias=TableAlias(this=to_identifier(alias)) if alias else None,
8114    )

Build a Table.

Arguments:
  • table: Table name.
  • db: Database name.
  • catalog: Catalog name.
  • quote: Whether to force quotes on the table's identifiers.
  • alias: Table's alias.
Returns:

The new Table instance.

def values( values: Iterable[Tuple[Any, ...]], alias: Optional[str] = None, columns: Union[Iterable[str], Dict[str, DataType], NoneType] = None) -> Values:
8117def values(
8118    values: t.Iterable[t.Tuple[t.Any, ...]],
8119    alias: t.Optional[str] = None,
8120    columns: t.Optional[t.Iterable[str] | t.Dict[str, DataType]] = None,
8121) -> Values:
8122    """Build VALUES statement.
8123
8124    Example:
8125        >>> values([(1, '2')]).sql()
8126        "VALUES (1, '2')"
8127
8128    Args:
8129        values: values statements that will be converted to SQL
8130        alias: optional alias
8131        columns: Optional list of ordered column names or ordered dictionary of column names to types.
8132         If either are provided then an alias is also required.
8133
8134    Returns:
8135        Values: the Values expression object
8136    """
8137    if columns and not alias:
8138        raise ValueError("Alias is required when providing columns")
8139
8140    return Values(
8141        expressions=[convert(tup) for tup in values],
8142        alias=(
8143            TableAlias(this=to_identifier(alias), columns=[to_identifier(x) for x in columns])
8144            if columns
8145            else (TableAlias(this=to_identifier(alias)) if alias else None)
8146        ),
8147    )

Build VALUES statement.

Example:
>>> values([(1, '2')]).sql()
"VALUES (1, '2')"
Arguments:
  • values: values statements that will be converted to SQL
  • alias: optional alias
  • columns: Optional list of ordered column names or ordered dictionary of column names to types. If either are provided then an alias is also required.
Returns:

Values: the Values expression object

def var( name: Union[str, Expression, NoneType]) -> Var:
8150def var(name: t.Optional[ExpOrStr]) -> Var:
8151    """Build a SQL variable.
8152
8153    Example:
8154        >>> repr(var('x'))
8155        'Var(this=x)'
8156
8157        >>> repr(var(column('x', table='y')))
8158        'Var(this=x)'
8159
8160    Args:
8161        name: The name of the var or an expression who's name will become the var.
8162
8163    Returns:
8164        The new variable node.
8165    """
8166    if not name:
8167        raise ValueError("Cannot convert empty name into var.")
8168
8169    if isinstance(name, Expression):
8170        name = name.name
8171    return Var(this=name)

Build a SQL variable.

Example:
>>> repr(var('x'))
'Var(this=x)'
>>> repr(var(column('x', table='y')))
'Var(this=x)'
Arguments:
  • name: The name of the var or an expression who's name will become the var.
Returns:

The new variable node.

def rename_table( old_name: str | Table, new_name: str | Table, dialect: Union[str, sqlglot.dialects.Dialect, Type[sqlglot.dialects.Dialect], NoneType] = None) -> Alter:
8174def rename_table(
8175    old_name: str | Table,
8176    new_name: str | Table,
8177    dialect: DialectType = None,
8178) -> Alter:
8179    """Build ALTER TABLE... RENAME... expression
8180
8181    Args:
8182        old_name: The old name of the table
8183        new_name: The new name of the table
8184        dialect: The dialect to parse the table.
8185
8186    Returns:
8187        Alter table expression
8188    """
8189    old_table = to_table(old_name, dialect=dialect)
8190    new_table = to_table(new_name, dialect=dialect)
8191    return Alter(
8192        this=old_table,
8193        kind="TABLE",
8194        actions=[
8195            AlterRename(this=new_table),
8196        ],
8197    )

Build ALTER TABLE... RENAME... expression

Arguments:
  • old_name: The old name of the table
  • new_name: The new name of the table
  • dialect: The dialect to parse the table.
Returns:

Alter table expression

def rename_column( table_name: str | Table, old_column_name: str | Column, new_column_name: str | Column, exists: Optional[bool] = None, dialect: Union[str, sqlglot.dialects.Dialect, Type[sqlglot.dialects.Dialect], NoneType] = None) -> Alter:
8200def rename_column(
8201    table_name: str | Table,
8202    old_column_name: str | Column,
8203    new_column_name: str | Column,
8204    exists: t.Optional[bool] = None,
8205    dialect: DialectType = None,
8206) -> Alter:
8207    """Build ALTER TABLE... RENAME COLUMN... expression
8208
8209    Args:
8210        table_name: Name of the table
8211        old_column: The old name of the column
8212        new_column: The new name of the column
8213        exists: Whether to add the `IF EXISTS` clause
8214        dialect: The dialect to parse the table/column.
8215
8216    Returns:
8217        Alter table expression
8218    """
8219    table = to_table(table_name, dialect=dialect)
8220    old_column = to_column(old_column_name, dialect=dialect)
8221    new_column = to_column(new_column_name, dialect=dialect)
8222    return Alter(
8223        this=table,
8224        kind="TABLE",
8225        actions=[
8226            RenameColumn(this=old_column, to=new_column, exists=exists),
8227        ],
8228    )

Build ALTER TABLE... RENAME COLUMN... expression

Arguments:
  • table_name: Name of the table
  • old_column: The old name of the column
  • new_column: The new name of the column
  • exists: Whether to add the IF EXISTS clause
  • dialect: The dialect to parse the table/column.
Returns:

Alter table expression

def convert(value: Any, copy: bool = False) -> Expression:
8231def convert(value: t.Any, copy: bool = False) -> Expression:
8232    """Convert a python value into an expression object.
8233
8234    Raises an error if a conversion is not possible.
8235
8236    Args:
8237        value: A python object.
8238        copy: Whether to copy `value` (only applies to Expressions and collections).
8239
8240    Returns:
8241        The equivalent expression object.
8242    """
8243    if isinstance(value, Expression):
8244        return maybe_copy(value, copy)
8245    if isinstance(value, str):
8246        return Literal.string(value)
8247    if isinstance(value, bool):
8248        return Boolean(this=value)
8249    if value is None or (isinstance(value, float) and math.isnan(value)):
8250        return null()
8251    if isinstance(value, numbers.Number):
8252        return Literal.number(value)
8253    if isinstance(value, bytes):
8254        return HexString(this=value.hex())
8255    if isinstance(value, datetime.datetime):
8256        datetime_literal = Literal.string(value.isoformat(sep=" "))
8257
8258        tz = None
8259        if value.tzinfo:
8260            # this works for zoneinfo.ZoneInfo, pytz.timezone and datetime.datetime.utc to return IANA timezone names like "America/Los_Angeles"
8261            # instead of abbreviations like "PDT". This is for consistency with other timezone handling functions in SQLGlot
8262            tz = Literal.string(str(value.tzinfo))
8263
8264        return TimeStrToTime(this=datetime_literal, zone=tz)
8265    if isinstance(value, datetime.date):
8266        date_literal = Literal.string(value.strftime("%Y-%m-%d"))
8267        return DateStrToDate(this=date_literal)
8268    if isinstance(value, tuple):
8269        if hasattr(value, "_fields"):
8270            return Struct(
8271                expressions=[
8272                    PropertyEQ(
8273                        this=to_identifier(k), expression=convert(getattr(value, k), copy=copy)
8274                    )
8275                    for k in value._fields
8276                ]
8277            )
8278        return Tuple(expressions=[convert(v, copy=copy) for v in value])
8279    if isinstance(value, list):
8280        return Array(expressions=[convert(v, copy=copy) for v in value])
8281    if isinstance(value, dict):
8282        return Map(
8283            keys=Array(expressions=[convert(k, copy=copy) for k in value]),
8284            values=Array(expressions=[convert(v, copy=copy) for v in value.values()]),
8285        )
8286    if hasattr(value, "__dict__"):
8287        return Struct(
8288            expressions=[
8289                PropertyEQ(this=to_identifier(k), expression=convert(v, copy=copy))
8290                for k, v in value.__dict__.items()
8291            ]
8292        )
8293    raise ValueError(f"Cannot convert {value}")

Convert a python value into an expression object.

Raises an error if a conversion is not possible.

Arguments:
  • value: A python object.
  • copy: Whether to copy value (only applies to Expressions and collections).
Returns:

The equivalent expression object.

def replace_children( expression: Expression, fun: Callable, *args, **kwargs) -> None:
8296def replace_children(expression: Expression, fun: t.Callable, *args, **kwargs) -> None:
8297    """
8298    Replace children of an expression with the result of a lambda fun(child) -> exp.
8299    """
8300    for k, v in tuple(expression.args.items()):
8301        is_list_arg = type(v) is list
8302
8303        child_nodes = v if is_list_arg else [v]
8304        new_child_nodes = []
8305
8306        for cn in child_nodes:
8307            if isinstance(cn, Expression):
8308                for child_node in ensure_collection(fun(cn, *args, **kwargs)):
8309                    new_child_nodes.append(child_node)
8310            else:
8311                new_child_nodes.append(cn)
8312
8313        expression.set(k, new_child_nodes if is_list_arg else seq_get(new_child_nodes, 0))

Replace children of an expression with the result of a lambda fun(child) -> exp.

def replace_tree( expression: Expression, fun: Callable, prune: Optional[Callable[[Expression], bool]] = None) -> Expression:
8316def replace_tree(
8317    expression: Expression,
8318    fun: t.Callable,
8319    prune: t.Optional[t.Callable[[Expression], bool]] = None,
8320) -> Expression:
8321    """
8322    Replace an entire tree with the result of function calls on each node.
8323
8324    This will be traversed in reverse dfs, so leaves first.
8325    If new nodes are created as a result of function calls, they will also be traversed.
8326    """
8327    stack = list(expression.dfs(prune=prune))
8328
8329    while stack:
8330        node = stack.pop()
8331        new_node = fun(node)
8332
8333        if new_node is not node:
8334            node.replace(new_node)
8335
8336            if isinstance(new_node, Expression):
8337                stack.append(new_node)
8338
8339    return new_node

Replace an entire tree with the result of function calls on each node.

This will be traversed in reverse dfs, so leaves first. If new nodes are created as a result of function calls, they will also be traversed.

def column_table_names( expression: Expression, exclude: str = '') -> Set[str]:
8342def column_table_names(expression: Expression, exclude: str = "") -> t.Set[str]:
8343    """
8344    Return all table names referenced through columns in an expression.
8345
8346    Example:
8347        >>> import sqlglot
8348        >>> sorted(column_table_names(sqlglot.parse_one("a.b AND c.d AND c.e")))
8349        ['a', 'c']
8350
8351    Args:
8352        expression: expression to find table names.
8353        exclude: a table name to exclude
8354
8355    Returns:
8356        A list of unique names.
8357    """
8358    return {
8359        table
8360        for table in (column.table for column in expression.find_all(Column))
8361        if table and table != exclude
8362    }

Return all table names referenced through columns in an expression.

Example:
>>> import sqlglot
>>> sorted(column_table_names(sqlglot.parse_one("a.b AND c.d AND c.e")))
['a', 'c']
Arguments:
  • expression: expression to find table names.
  • exclude: a table name to exclude
Returns:

A list of unique names.

def table_name( table: Table | str, dialect: Union[str, sqlglot.dialects.Dialect, Type[sqlglot.dialects.Dialect], NoneType] = None, identify: bool = False) -> str:
8365def table_name(table: Table | str, dialect: DialectType = None, identify: bool = False) -> str:
8366    """Get the full name of a table as a string.
8367
8368    Args:
8369        table: Table expression node or string.
8370        dialect: The dialect to generate the table name for.
8371        identify: Determines when an identifier should be quoted. Possible values are:
8372            False (default): Never quote, except in cases where it's mandatory by the dialect.
8373            True: Always quote.
8374
8375    Examples:
8376        >>> from sqlglot import exp, parse_one
8377        >>> table_name(parse_one("select * from a.b.c").find(exp.Table))
8378        'a.b.c'
8379
8380    Returns:
8381        The table name.
8382    """
8383
8384    table = maybe_parse(table, into=Table, dialect=dialect)
8385
8386    if not table:
8387        raise ValueError(f"Cannot parse {table}")
8388
8389    return ".".join(
8390        (
8391            part.sql(dialect=dialect, identify=True, copy=False, comments=False)
8392            if identify or not SAFE_IDENTIFIER_RE.match(part.name)
8393            else part.name
8394        )
8395        for part in table.parts
8396    )

Get the full name of a table as a string.

Arguments:
  • table: Table expression node or string.
  • dialect: The dialect to generate the table name for.
  • identify: Determines when an identifier should be quoted. Possible values are: False (default): Never quote, except in cases where it's mandatory by the dialect. True: Always quote.
Examples:
>>> from sqlglot import exp, parse_one
>>> table_name(parse_one("select * from a.b.c").find(exp.Table))
'a.b.c'
Returns:

The table name.

def normalize_table_name( table: str | Table, dialect: Union[str, sqlglot.dialects.Dialect, Type[sqlglot.dialects.Dialect], NoneType] = None, copy: bool = True) -> str:
8399def normalize_table_name(table: str | Table, dialect: DialectType = None, copy: bool = True) -> str:
8400    """Returns a case normalized table name without quotes.
8401
8402    Args:
8403        table: the table to normalize
8404        dialect: the dialect to use for normalization rules
8405        copy: whether to copy the expression.
8406
8407    Examples:
8408        >>> normalize_table_name("`A-B`.c", dialect="bigquery")
8409        'A-B.c'
8410    """
8411    from sqlglot.optimizer.normalize_identifiers import normalize_identifiers
8412
8413    return ".".join(
8414        p.name
8415        for p in normalize_identifiers(
8416            to_table(table, dialect=dialect, copy=copy), dialect=dialect
8417        ).parts
8418    )

Returns a case normalized table name without quotes.

Arguments:
  • table: the table to normalize
  • dialect: the dialect to use for normalization rules
  • copy: whether to copy the expression.
Examples:
>>> normalize_table_name("`A-B`.c", dialect="bigquery")
'A-B.c'
def replace_tables( expression: ~E, mapping: Dict[str, str], dialect: Union[str, sqlglot.dialects.Dialect, Type[sqlglot.dialects.Dialect], NoneType] = None, copy: bool = True) -> ~E:
8421def replace_tables(
8422    expression: E, mapping: t.Dict[str, str], dialect: DialectType = None, copy: bool = True
8423) -> E:
8424    """Replace all tables in expression according to the mapping.
8425
8426    Args:
8427        expression: expression node to be transformed and replaced.
8428        mapping: mapping of table names.
8429        dialect: the dialect of the mapping table
8430        copy: whether to copy the expression.
8431
8432    Examples:
8433        >>> from sqlglot import exp, parse_one
8434        >>> replace_tables(parse_one("select * from a.b"), {"a.b": "c"}).sql()
8435        'SELECT * FROM c /* a.b */'
8436
8437    Returns:
8438        The mapped expression.
8439    """
8440
8441    mapping = {normalize_table_name(k, dialect=dialect): v for k, v in mapping.items()}
8442
8443    def _replace_tables(node: Expression) -> Expression:
8444        if isinstance(node, Table) and node.meta.get("replace") is not False:
8445            original = normalize_table_name(node, dialect=dialect)
8446            new_name = mapping.get(original)
8447
8448            if new_name:
8449                table = to_table(
8450                    new_name,
8451                    **{k: v for k, v in node.args.items() if k not in TABLE_PARTS},
8452                    dialect=dialect,
8453                )
8454                table.add_comments([original])
8455                return table
8456        return node
8457
8458    return expression.transform(_replace_tables, copy=copy)  # type: ignore

Replace all tables in expression according to the mapping.

Arguments:
  • expression: expression node to be transformed and replaced.
  • mapping: mapping of table names.
  • dialect: the dialect of the mapping table
  • copy: whether to copy the expression.
Examples:
>>> from sqlglot import exp, parse_one
>>> replace_tables(parse_one("select * from a.b"), {"a.b": "c"}).sql()
'SELECT * FROM c /* a.b */'
Returns:

The mapped expression.

def replace_placeholders( expression: Expression, *args, **kwargs) -> Expression:
8461def replace_placeholders(expression: Expression, *args, **kwargs) -> Expression:
8462    """Replace placeholders in an expression.
8463
8464    Args:
8465        expression: expression node to be transformed and replaced.
8466        args: positional names that will substitute unnamed placeholders in the given order.
8467        kwargs: keyword arguments that will substitute named placeholders.
8468
8469    Examples:
8470        >>> from sqlglot import exp, parse_one
8471        >>> replace_placeholders(
8472        ...     parse_one("select * from :tbl where ? = ?"),
8473        ...     exp.to_identifier("str_col"), "b", tbl=exp.to_identifier("foo")
8474        ... ).sql()
8475        "SELECT * FROM foo WHERE str_col = 'b'"
8476
8477    Returns:
8478        The mapped expression.
8479    """
8480
8481    def _replace_placeholders(node: Expression, args, **kwargs) -> Expression:
8482        if isinstance(node, Placeholder):
8483            if node.this:
8484                new_name = kwargs.get(node.this)
8485                if new_name is not None:
8486                    return convert(new_name)
8487            else:
8488                try:
8489                    return convert(next(args))
8490                except StopIteration:
8491                    pass
8492        return node
8493
8494    return expression.transform(_replace_placeholders, iter(args), **kwargs)

Replace placeholders in an expression.

Arguments:
  • expression: expression node to be transformed and replaced.
  • args: positional names that will substitute unnamed placeholders in the given order.
  • kwargs: keyword arguments that will substitute named placeholders.
Examples:
>>> from sqlglot import exp, parse_one
>>> replace_placeholders(
...     parse_one("select * from :tbl where ? = ?"),
...     exp.to_identifier("str_col"), "b", tbl=exp.to_identifier("foo")
... ).sql()
"SELECT * FROM foo WHERE str_col = 'b'"
Returns:

The mapped expression.

def expand( expression: Expression, sources: Dict[str, Query], dialect: Union[str, sqlglot.dialects.Dialect, Type[sqlglot.dialects.Dialect], NoneType] = None, copy: bool = True) -> Expression:
8497def expand(
8498    expression: Expression,
8499    sources: t.Dict[str, Query],
8500    dialect: DialectType = None,
8501    copy: bool = True,
8502) -> Expression:
8503    """Transforms an expression by expanding all referenced sources into subqueries.
8504
8505    Examples:
8506        >>> from sqlglot import parse_one
8507        >>> expand(parse_one("select * from x AS z"), {"x": parse_one("select * from y")}).sql()
8508        'SELECT * FROM (SELECT * FROM y) AS z /* source: x */'
8509
8510        >>> expand(parse_one("select * from x AS z"), {"x": parse_one("select * from y"), "y": parse_one("select * from z")}).sql()
8511        'SELECT * FROM (SELECT * FROM (SELECT * FROM z) AS y /* source: y */) AS z /* source: x */'
8512
8513    Args:
8514        expression: The expression to expand.
8515        sources: A dictionary of name to Queries.
8516        dialect: The dialect of the sources dict.
8517        copy: Whether to copy the expression during transformation. Defaults to True.
8518
8519    Returns:
8520        The transformed expression.
8521    """
8522    sources = {normalize_table_name(k, dialect=dialect): v for k, v in sources.items()}
8523
8524    def _expand(node: Expression):
8525        if isinstance(node, Table):
8526            name = normalize_table_name(node, dialect=dialect)
8527            source = sources.get(name)
8528            if source:
8529                subquery = source.subquery(node.alias or name)
8530                subquery.comments = [f"source: {name}"]
8531                return subquery.transform(_expand, copy=False)
8532        return node
8533
8534    return expression.transform(_expand, copy=copy)

Transforms an expression by expanding all referenced sources into subqueries.

Examples:
>>> from sqlglot import parse_one
>>> expand(parse_one("select * from x AS z"), {"x": parse_one("select * from y")}).sql()
'SELECT * FROM (SELECT * FROM y) AS z /* source: x */'
>>> expand(parse_one("select * from x AS z"), {"x": parse_one("select * from y"), "y": parse_one("select * from z")}).sql()
'SELECT * FROM (SELECT * FROM (SELECT * FROM z) AS y /* source: y */) AS z /* source: x */'
Arguments:
  • expression: The expression to expand.
  • sources: A dictionary of name to Queries.
  • dialect: The dialect of the sources dict.
  • copy: Whether to copy the expression during transformation. Defaults to True.
Returns:

The transformed expression.

def func( name: str, *args, copy: bool = True, dialect: Union[str, sqlglot.dialects.Dialect, Type[sqlglot.dialects.Dialect], NoneType] = None, **kwargs) -> Func:
8537def func(name: str, *args, copy: bool = True, dialect: DialectType = None, **kwargs) -> Func:
8538    """
8539    Returns a Func expression.
8540
8541    Examples:
8542        >>> func("abs", 5).sql()
8543        'ABS(5)'
8544
8545        >>> func("cast", this=5, to=DataType.build("DOUBLE")).sql()
8546        'CAST(5 AS DOUBLE)'
8547
8548    Args:
8549        name: the name of the function to build.
8550        args: the args used to instantiate the function of interest.
8551        copy: whether to copy the argument expressions.
8552        dialect: the source dialect.
8553        kwargs: the kwargs used to instantiate the function of interest.
8554
8555    Note:
8556        The arguments `args` and `kwargs` are mutually exclusive.
8557
8558    Returns:
8559        An instance of the function of interest, or an anonymous function, if `name` doesn't
8560        correspond to an existing `sqlglot.expressions.Func` class.
8561    """
8562    if args and kwargs:
8563        raise ValueError("Can't use both args and kwargs to instantiate a function.")
8564
8565    from sqlglot.dialects.dialect import Dialect
8566
8567    dialect = Dialect.get_or_raise(dialect)
8568
8569    converted: t.List[Expression] = [maybe_parse(arg, dialect=dialect, copy=copy) for arg in args]
8570    kwargs = {key: maybe_parse(value, dialect=dialect, copy=copy) for key, value in kwargs.items()}
8571
8572    constructor = dialect.parser_class.FUNCTIONS.get(name.upper())
8573    if constructor:
8574        if converted:
8575            if "dialect" in constructor.__code__.co_varnames:
8576                function = constructor(converted, dialect=dialect)
8577            else:
8578                function = constructor(converted)
8579        elif constructor.__name__ == "from_arg_list":
8580            function = constructor.__self__(**kwargs)  # type: ignore
8581        else:
8582            constructor = FUNCTION_BY_NAME.get(name.upper())
8583            if constructor:
8584                function = constructor(**kwargs)
8585            else:
8586                raise ValueError(
8587                    f"Unable to convert '{name}' into a Func. Either manually construct "
8588                    "the Func expression of interest or parse the function call."
8589                )
8590    else:
8591        kwargs = kwargs or {"expressions": converted}
8592        function = Anonymous(this=name, **kwargs)
8593
8594    for error_message in function.error_messages(converted):
8595        raise ValueError(error_message)
8596
8597    return function

Returns a Func expression.

Examples:
>>> func("abs", 5).sql()
'ABS(5)'
>>> func("cast", this=5, to=DataType.build("DOUBLE")).sql()
'CAST(5 AS DOUBLE)'
Arguments:
  • name: the name of the function to build.
  • args: the args used to instantiate the function of interest.
  • copy: whether to copy the argument expressions.
  • dialect: the source dialect.
  • kwargs: the kwargs used to instantiate the function of interest.
Note:

The arguments args and kwargs are mutually exclusive.

Returns:

An instance of the function of interest, or an anonymous function, if name doesn't correspond to an existing sqlglot.expressions.Func class.

def case( expression: Union[str, Expression, NoneType] = None, **opts) -> Case:
8600def case(
8601    expression: t.Optional[ExpOrStr] = None,
8602    **opts,
8603) -> Case:
8604    """
8605    Initialize a CASE statement.
8606
8607    Example:
8608        case().when("a = 1", "foo").else_("bar")
8609
8610    Args:
8611        expression: Optionally, the input expression (not all dialects support this)
8612        **opts: Extra keyword arguments for parsing `expression`
8613    """
8614    if expression is not None:
8615        this = maybe_parse(expression, **opts)
8616    else:
8617        this = None
8618    return Case(this=this, ifs=[])

Initialize a CASE statement.

Example:

case().when("a = 1", "foo").else_("bar")

Arguments:
  • expression: Optionally, the input expression (not all dialects support this)
  • **opts: Extra keyword arguments for parsing expression
def array( *expressions: Union[str, Expression], copy: bool = True, dialect: Union[str, sqlglot.dialects.Dialect, Type[sqlglot.dialects.Dialect], NoneType] = None, **kwargs) -> Array:
8621def array(
8622    *expressions: ExpOrStr, copy: bool = True, dialect: DialectType = None, **kwargs
8623) -> Array:
8624    """
8625    Returns an array.
8626
8627    Examples:
8628        >>> array(1, 'x').sql()
8629        'ARRAY(1, x)'
8630
8631    Args:
8632        expressions: the expressions to add to the array.
8633        copy: whether to copy the argument expressions.
8634        dialect: the source dialect.
8635        kwargs: the kwargs used to instantiate the function of interest.
8636
8637    Returns:
8638        An array expression.
8639    """
8640    return Array(
8641        expressions=[
8642            maybe_parse(expression, copy=copy, dialect=dialect, **kwargs)
8643            for expression in expressions
8644        ]
8645    )

Returns an array.

Examples:
>>> array(1, 'x').sql()
'ARRAY(1, x)'
Arguments:
  • expressions: the expressions to add to the array.
  • copy: whether to copy the argument expressions.
  • dialect: the source dialect.
  • kwargs: the kwargs used to instantiate the function of interest.
Returns:

An array expression.

def tuple_( *expressions: Union[str, Expression], copy: bool = True, dialect: Union[str, sqlglot.dialects.Dialect, Type[sqlglot.dialects.Dialect], NoneType] = None, **kwargs) -> Tuple:
8648def tuple_(
8649    *expressions: ExpOrStr, copy: bool = True, dialect: DialectType = None, **kwargs
8650) -> Tuple:
8651    """
8652    Returns an tuple.
8653
8654    Examples:
8655        >>> tuple_(1, 'x').sql()
8656        '(1, x)'
8657
8658    Args:
8659        expressions: the expressions to add to the tuple.
8660        copy: whether to copy the argument expressions.
8661        dialect: the source dialect.
8662        kwargs: the kwargs used to instantiate the function of interest.
8663
8664    Returns:
8665        A tuple expression.
8666    """
8667    return Tuple(
8668        expressions=[
8669            maybe_parse(expression, copy=copy, dialect=dialect, **kwargs)
8670            for expression in expressions
8671        ]
8672    )

Returns an tuple.

Examples:
>>> tuple_(1, 'x').sql()
'(1, x)'
Arguments:
  • expressions: the expressions to add to the tuple.
  • copy: whether to copy the argument expressions.
  • dialect: the source dialect.
  • kwargs: the kwargs used to instantiate the function of interest.
Returns:

A tuple expression.

def true() -> Boolean:
8675def true() -> Boolean:
8676    """
8677    Returns a true Boolean expression.
8678    """
8679    return Boolean(this=True)

Returns a true Boolean expression.

def false() -> Boolean:
8682def false() -> Boolean:
8683    """
8684    Returns a false Boolean expression.
8685    """
8686    return Boolean(this=False)

Returns a false Boolean expression.

def null() -> Null:
8689def null() -> Null:
8690    """
8691    Returns a Null expression.
8692    """
8693    return Null()

Returns a Null expression.

NONNULL_CONSTANTS = (<class 'Literal'>, <class 'Boolean'>)
CONSTANTS = (<class 'Literal'>, <class 'Boolean'>, <class 'Null'>)